kernel 异步
来源:互联网 发布:国家药监局数据网查询 编辑:程序博客网 时间:2024/06/07 12:40
异步
一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询状态
用户空间处理一个设备释放的信号的三项工作:
/* specify handler for signal */signal(SIGIO, input_handler);/* current process owns this fd */fcntl(STDIN_FILENO, F_SETOWN, getpid());/* launch the async mechanism */flags = fcntl(STDIN_FILENO, F_GETFL);fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC);
异步通知的设备驱动模版
struct xxx_dev { struct cdev cdev; ... struct fasync_struct *async_queue;};static int xxx_fasync(int fd, struct file *filp, int mode){ struct xxx_dev *dev = filp->private_data; /* when file has been set as async mode, add fd into async queue */ return fasync_helper(fd, filp, mode, &dev->async_queue);}static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){ struct xxx_dev *dev = filp->private_data; ... /* launch async read signal */ if (dev->async_queue) kill_fasync(&dev->async_queue, SIGIO, POLL_IN); ...}static int xxx_release(struct inode *inode, struct file *filp){ /* delete fd from async_queue */ xxx_fasync(-1, filp, 0); ... return 0;}
AIO
异步I/O的时序:
发起I/O动作后,并不等待I/O结束,
+ 要么过一段时间来查询之前的I/O请求完成情况
+ 要么I/O请求完成了会自动调用绑定的回调函数
AIO 多种实现
在用户空间的glibc库中实现
基于线程实现,通过 pthread_cond_signal() 实现线程间同步
1. aio_read()
2. aio_write()
3. aio_error() 确定请求的状态
4. aio_return()
5. aio_suspend()
6. aio_cancel()
7. lio_listio()
- 采用 aio_return() 不断询问的方式
#include <aio.h>int fd, ret;struct aiocb my_aiocb;fd = open("file.txt", O_RDONLY);if (fd < 0) printf("open failed\n");bzero(&my_aiocb, sizeof(struct aiocb));my_aiocb.aio_buf = malloc(BUFSIZE + 1);if (!my_aiocb.aio_buf) printf("malloc failed\n");my_aiocb.aio_fildes = fd;my_aiocb.aio_nbytes = BUFSIZE;my_aiocb.aio_offset = 0;ret = aio_read(&my_aiocb);if (ret < 0) printf("aio_read failed\n");while (aio_error(&my_aiocb) == EINPROGRESS) continue;if ((ret = aio_return(&my_aiocb)) > 0) /* read success */else /* read failed */
- 采用 aio_suspend() 阻塞的方式
struct aiocb *cblist[MAX_LIST];bzero((char *)cblist, sizeof(cblist));cblist[0] = &my_aiocb;...ret = aio_read(&my_aiocb);ret = aio_suspend(cblist, MAX_LIST, NULL);
- 采用 lio_listio() 操作多个io control block
struct aiocb aiocb1, aiocb2;struct aiocb *cblist[MAX_LIST];aiocb1.aio_fildes = fd;aiocb1.aio_buf = malloc(BUFSIZE + 1);aiocb1.aio_nbytes = BUFSIZE;aiocb1.aio_offset = 0;aiocb1.aio_lio_opcode = LIO_READ;...bzero((char *)cblist, sizeof(cblist));cblist[0] = &aiocb1;cblist[1] = &aiocb2;.../* LIO_WAIT means block mode */ret = lio_listio(LIO_WAIT, list, MAX_LIST, NULL);
内核提供 libaio 的系统调用
AIO的读写请求都用 io_submit() 下发。下发前通过 io_prep_pwrite() 和 io_prep_pread() 生成iocb的结构体,作为 io_submit() 的参数。这个结构体指定了读写类型、起始地址、长度和设备标识符等信息。读写请求下发之后,使用 io_getevents() 函数等待I/O完成事件。 io_set_callback() 设置一个AIO完成的回调函数。
file_operation 包含3个与AIO相关的成员函数:
* aio_read()
* aio_write()
* aio_fsync()
io_submit() 间接调用 file_operation 中 aio_read() 和 aio_write()
总结
内核包含对AIO的支持,为用户空间提供了统一的异步I/O接口。glibc也提供了不依赖内核的用户空间AIO支持。
- kernel 异步
- Kernel
- kernel
- kernel
- kernel
- kernel
- kernel
- kernel
- Kernel
- 异步
- 异步
- 异步
- 异步
- 异步
- 异步
- 异步
- 异步
- 异步
- 面向对象总结
- List
- Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索
- .vimrc
- ARM U-Boot SPL过程浅析
- kernel 异步
- 前端页面二次确认功能
- linux ubuntu vi编辑文件信息工具使用应用
- Android开发之引导页
- 模拟登录学校的学生服务子系统查询成绩
- gitlab安装
- 空 比较对象 遇到的问题,==, null, (注意事项)
- Java连接mysql数据库
- 通道抠图的步骤