驱动三种IO模型

非阻塞IO
在应用程序中读取硬件数据时,不管硬件数据有没有准备好,read()函数不会阻塞,而是继续向下执行


阻塞IO
当应用程序中读取硬件数据时,如果硬件数据没有准备好,此时进程阻塞在read()函数位置,直到硬件数据就绪,通过read()函数读取硬件数据,程序向下执行,进程阻塞等待数据时处于休眠态

休眠状态分为两种:

D uninterruptible sleep (usually IO)     不可中断休眠态,不能通过外部信号将进程结束

S interruptible sleep (waiting for an event to complete)    可中断休眠态

相关API

1.定义等待队列头
wait_queue_head_t wq_head;
2.初始化等待队列头
init_waitqueue_head(&wq_head);
3.wait_event(wq_head, condition)  
功能:检查condition的真假,如果为真,则函数执行结束,如果为假,将进程切换到不可中断休眠状态
参数:wq_head:等待队列头
    condition:标志变量
4.wait_event_interruptible(wq_head, condition) 
   功能:检查condition的真假,如果为真,则函数执行结束,如果为假,将进程切换到可中断休眠状态
参数:wq_head:等待队列头
    condition:标志变量
返回值:如果condition为真则返回0,如果被一个信号中断,则返回错误码-ERESTARTSYS 

5.wake_up(&wq_head)
功能:将不可中断休眠态的进程唤醒,当执行这个函数时如果condition为假,则进程被唤醒后会再次休眠
参数:等待队列头地址
6.wake_up_interruptible(&wq_head)
功能:将  可中断休眠态的进程唤醒当执行这个函数时如果condition为假,则进程被唤醒后会再次休眠
参数:等待队列头地址

IO多路复用

如果要在一个进程中同时监听多个硬件的数据,就需要使用IO多路复用。其基本思想是在用户空间中将监听的事件文件描述符添加到事件集合中,调用函数进行判断集合中文件描述符对应的硬件数据是否准备就绪,如果没有一个事件发生,将进程切换到休眠状态(可中断休眠状态)。当有一个或者多个硬件数据准备好了,将休眠的进程唤醒,对准备好的硬件数据进行读写

IO多路复用的实现机制有三种:select/poll/epoll

select:

(1)阻塞函数,让内核检测指定文件描述符集合中,是否有文件描述符准备就绪 

(2)当文件描述符准备就绪后,该函数解除阻塞。

(3)当事件产生后,集合中会只剩下触发事件的文件描述符。

poll:阻塞函数,让内核检测指定文件描述符集合中,是否有文件描述符准备就绪,当文件描述符准备就绪后,该函数解除阻塞。

epoll核心操作:一颗树、一张表、三个接口

epoll相关API

 #include <sys/epoll.h>
   1.int epoll_create(int size);
   功能:创建一个新的epoll
   参数:
       size:大于0的整数
   返回值:成功返回用于操作epoll的文件描述符,失败返回错误码
   2.int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
   功能:进行epoll管理
   参数:
       epfd:epoll_create生成的文件描述符
       op:管理的类型选项
            EPOLL_CTL_ADD:用于在epoll上添加文件描述符
            EPOLL_CTL_MOD:用于修改文件描述符事件类型
            EPOLL_CTL_DEL:从epoll上移除指定的文件描述符
       fd:要操作的文件描述符
       event:设置文件描述符属性的变量
           struct epoll_event {
               uint32_t     events;      /* Epoll events */
                       //EPOLLIN:读
                       //EPOLLOUT:写
               epoll_data_t data;        /* User data variable */
           };
            typedef union epoll_data {
               void        *ptr;
               int          fd;《=======使用这个
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;
返回值:  成功返回0,失败返回错误码                    
   3.int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
功能:阻塞等待事件发生
参数:
   epfd:epoll_create生成的文件描述符
   events: 存放发生的事件的文件描述符数组的首地址
   maxevents:监听的文件描述符最大个数
   timeout:设置超时事件   毫秒级   -1表示不关注超时 >0超时事件
返回值:
    >0:发生事件的文件描述符个数
    ==0:超时时间到达
    <0:失败

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值