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代码中已注释不让使用,将在代码中剔除
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值