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代码中已注释不让使用,将在代码中剔除
使用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代码中已注释不让使用,将在代码中剔除
相关文章推荐
- unix/linux socket设置非阻塞io
- [linux] 将socket设置为非阻塞(non-blocking)
- Linux下面socket编程的非阻塞TCP研究
- Linux信号机制之信号阻塞
- 基于socket的Linux网络聊天程序--单线程非阻塞客户端
- Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结
- linux非阻塞socket教程
- linux 客户端 Socket 非阻塞connect编程(正文)
- Linux内核开发之阻塞非阻塞IO----轮询操作
- [linux] 将socket设置为非阻塞(non-blocking)
- Linux下非阻塞getch实现示例
- Linux下面socket编程的非阻塞TCP研究
- unix/linux socket设置非阻塞
- linux下非阻塞的tcp研究(转)
- Linux下的阻塞(Block)
- 测试LINUX下进程间阻塞的代码
- linux下非阻塞的tcp研究
- linux api笔记(2) 网络编程(一)如何判断非阻塞套接字是否连接成功
- Linux下socket设置为非阻塞方式和fcntl系统调用
- linux 客户端 Socket 非阻塞connect编程