您的位置:首页 > 运维架构 > Linux

Linux阻塞和非阻塞

2017-07-07 09:25 127 查看
阻塞(休眠)调用是没有获得资源则挂起进程,被挂起的进程进入休眠状态,调用的函数只有在得到结果之后才返回,进程继续。非阻塞(休眠)是不能进行设备操作时不挂起,或返回,或反复查询,直到可以进行操作为止,被调用的函数不会阻塞当前进程,而会立刻返回。因为阻塞的进程会进入休眠状态,因此,必须确保有一个地方能够唤醒休眠的进程。唤醒进程的地方最大可能发生在中断里面,因为硬件资源获得的同时往往伴随着一个中断。
使用wait_event()函数使得进程睡眠;而在内核另一处有一个对应的wake_up()函数被调用wake_up() 应与wait_event() 或wait_event_timeout() 成对使用, 而wake_up_interruptible() 则应与wait_event_interruptible() 或wait_event_interruptible_timeout() 成对使用。wake_up() 可唤醒处于TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE 的进程,而wake_up_interruptible()只能唤醒处于TASK_INTERRUPTIBLE 的进程。  功能函数所在路径kernel/include/linux/wait.h, kernel/kernel/sched.c, kernel/kernel/wait.c.核心数据结构 等待队列struct __wait_queue_head {          spinlock_t lock;          struct list_head task_list;  };  typedef struct__wait_queue_head wait_queue_head_t;  
使用方法:涉及头文件kernel/include/linux/wait.h#include <linux/wait.h>
在数据结构体中定义 wait_queue_head_t  XX

进程通过执行下面步骤将自己加入到一个等待队列中:1) 调用DECLARE_WAITQUEUE(wait, current)定义和初始化一个等待队列头 //代替wait_queue_head_t my_queue和init_waitqueue_head(&my_queue);2) 调用add_wait_queue()把自己加入到等待队列中。该队列会在进程等待的条件满足时唤醒它。在其他地方写相关代码,在事件发生时,对等的队列执行wake_up()操作。3) 将进程状态变更为: TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE。4) 如果状态被置为TASK_INTERRUPTIBLE ,则信号唤醒进程。即为伪唤醒(唤醒不是因为事件的发生),因此检查并处理信号。5) 检查condition是否为真,为真则没必要休眠,如果不为真,则调用scheduled()。6) 当进程被唤醒的时候,它会再次检查条件是否为真。真就退出循环,否则再次调用scheduled()并一直重复这步操作。7) condition满足后,进程将自己设置为TASK_RUNNING 并通过remove_wait_queue()退出。

sleep_on系列函数在linux代码中已注释不让使用,将在代码中剔除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: