关于 wait_event_interruptible() 和 wake_up()的使用
来源:http://blog.csdn.net/allen6268198/article/details/8112551
1. 关于 wait_event_interruptible() 和 wake_up()的使用
读一下wait_event_interruptible()的源码,不难发现这个函数先将
当前进程的状态设置成TASK_INTERRUPTIBLE,然后调用schedule(),
而schedule()会将位于TASK_INTERRUPTIBLE状态的当前进程从runqueue
队列中删除。从runqueue队列中删除的结果是,当前这个进程将不再参
与调度,除非通过其他函数将这个进程重新放入这个runqueue队列中,
这就是wake_up()的作用了。
由于这一段代码位于一个由condition控制的for(;;)循环中,所以当由
shedule()返回时(当然是被wake_up之后,通过其他进程的schedule()而
再次调度本进程),如果条件condition不满足,本进程将自动再次被设
置为TASK_INTERRUPTIBLE状态,接下来执行schedule()的结果是再次被
从runqueue队列中删除。这时候就需要再次通过wake_up重新添加到
runqueue队列中。
如此反复,直到condition为真的时候被wake_up.
可见,成功地唤醒一个被wait_event_interruptible()的进程,需要满足:
在 1)condition为真的前提下,2) 调用wake_up()。
所以,如果你仅仅修改condition,那么只是满足其中一个条件,这个时候,
被wait_event_interruptible()起来的进程尚未位于runqueue队列中,因
此不会被 schedule。这个时候只要wake_up一下就立刻会重新进入运行调度。
2. 关于wait_event_interruptible的返回值
根据 wait_event_interruptible 的宏定义知:
1) 条件condition为真时调用这个函数将直接返回0,而当前进程不会
被 wait_event_interruptible和从runqueue队列中删除。
2) 如果要被wait_event_interruptible的当前进程有nonblocked pending
signals, 那么会直接返回-ERESTARTSYS(i.e. -512),当前进程不会
被wait_event_interruptible 和从runqueue队列中删除。
3) 其他情况下,当前进程会被正常的wait_event_interruptible,并从
runqueue队列中删除,进入TASK_INTERRUPTIBLE状态退出运行调度,
直到再次被唤醒加入runqueue队列中后而参与调度,将正常返回0。
附1:wait_event_interruptible 宏
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
注: C语言中{a,b, ..., x}的的值等于最后一项,即x,因此上述
宏的值是 __ret。
附2:wait_event_interruptible()和 wake_up的等效代码
wait_event_interruptible(wq, condition) /*等效没有考虑返回值*/
{
if (!(condition))
{
wait_queue_t _ _wait;
init_waitqueue_entry(&_ _wait, current);
add_wait_queue(&wq, &_ _wait);
for (;;)
{
set_current_state(TASK_INTERRUPTIBLE);
if (condition)
break;
schedule(); /* implicit call: del_from_runqueue(current)*/
}
current->state = TASK_RUNNING;
remove_wait_queue(&wq, &_ _wait);
}
}
void wake_up(wait_queue_head_t *q)
{
struct list_head *tmp;
wait_queue_t *curr;
list_for_each(tmp, &q->task_list)
{
curr = list_entry(tmp, wait_queue_t, task_list);
wake_up_process(curr->task);
/* implicit call: add_to_runqueue(curr->task);*/
if (curr->flags)
break;
}
}
关于 wait_event_interruptible() 和 wake_up()的使用的更多相关文章
- Linux学习 :中断处理机制 & poll机制
中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务 的程序中去,服务完毕后再返回去继续运行被暂时中断的程序 ...
- 【Linux驱动】内核等待队列
在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...
- 向linux内核中添加外部中断驱动模块
本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...
- I/O多路复用 SELECT POLL -- 内核实现
等待队列 先补充个基础知识――等待队列 认识 定义 wait_queue_head_t wait_queue; 初始化 init_waitqueue_head(&wait_queue); 等待 ...
- FL2440驱动添加(5)ADC驱动学习笔记
由图可知,模拟ADC分为两部分功能,一部分是触屏功能,另一部分就是普通ADC功能.分别可以产生INT_TC和INT_ADC 两个中断.该ADC模块总共有8个通道可以进行模拟信号的输入,分别是AIN0. ...
- linux设备驱动归纳总结(七):1.时间管理与内核延时【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-100005.html linux设备驱动归纳总结(七):1.时间管理与内核延时 xxxxxxxxxxx ...
- linux设备驱动归纳总结(三):5.阻塞型IO实现【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-60025.html linux设备驱动归纳总结(三):5.阻塞型IO实现 xxxxxxxxxxxxxx ...
- rtc关机闹钟7 jni层 com_android_server_AlarmManagerService
frameworks/base/services/core/jni/com_android_server_AlarmManagerService.cpp int AlarmImplAlarmDrive ...
- Linux驱动设计——阻塞和同步
阻塞和非阻塞是设备访问的两种基本方式,阻塞和非阻塞驱动程序使用时,经常会用到等待队列. 阻塞和非阻塞 阻塞操作是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作.被挂起的 ...
随机推荐
- 怎么调试EXC_BAD_ACCESS错误
当你遇到了一个EXC_BAD_ACCESS错误,我通常会给开发者几个建议: 1.在可执行选项中设置NSZombieEnabled参数,这有时会帮缩小问题的范围: 2.运行apple的内存检测工具,如 ...
- python环境配置selenium与IE、Chrome、Firefox、PhantomJS
安装.升级selenium pip install -U selenium 下载对应平台最新版的browser driver chrome: http://chromedriver.storage.g ...
- Java里的IO流里的FileInputStream 的读取并在前打印行数!
大家好!!新人求罩! import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException ...
- [PWA] 1. Intro to Service worker
Service worker stays between our browser and noetwork requests. It can help to fetch data from cache ...
- PHP 发布两个不用递归的树形数组构造函数(转)
<?php/** *创建父节点树形数组 * 参数 $ar 数组,邻接列表方式组织的数据 $id 数组中作为主键的下标或关联键名 $pid 数组中作为父键的下标或关联键名 * 返回 多维数组 ** ...
- hdu1258 Sum It Up (DFS)
Problem Description Given a specified total t and a list of n integers, find all distinct sums using ...
- 《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池
第11章 Android的线程和线程池 11.1 主线程和子线程 (1)在Java中默认情况下一个进程只有一个线程,也就是主线程,其他线程都是子线程,也叫工作线程.Android中的主线程主要处理和界 ...
- js动态添加table 数据tr td
成果库修改: 要求主题列表随成果类型改变而改变 网上查询资料后开工,在成果类型下拉框添加change()事件触发Dwr,查询主题集合——动态创建/编辑Table 概要代码 ...
- jQuery的css()方法
jQuery的css()方法下面的代码可以为div一次性设置多个样式属性<!DOCTYPE html><html><head><meta charset=&q ...
- text-overflow:ellipsis的巧妙运用
关键字: text-overflow:ellipsis 语法:text-overflow : clip | ellipsis 取值: clip :默认值 .不显示省略标记(...),而是简单的裁切. ...