linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠

转载 2015年11月18日 14:57:35
假设我们在 kernel 里产生一个 buffer,user 可以经由 read,write 等 system call 来读取或写资料到这个 buffer 里。如果有一个 user 写资料到 buffer 时,此时 buffer 已经满了。那请问你要如何去处理这种情形呢 ? 第一种,传给 user 一个错误讯息,说 buffer 已经满了,不能再写入。第二种,将 user 的要求 block 住, 等有人将 buffer 内容读走,留出空位时,再让 user 写入资料。但问题来了,你要怎么将 user 的要求 block 住。难道你要用
 while ( is_full );
write_to_buffer;
这样的程序代码吗? 想想看,如果你这样做会发生什么事? 第一,kernel会一直在这个 while 里执行。第二个,如果 kernel 一直在这个 while 里执行,表示它没有办法去 maintain系统的运作。那此时系统就相当于当掉了。在这里 is_full 是一个变量,当然,你可以让 is_full 是一个 function,在这个 function里会去做别的事让 kernel 可以运作,那系统就不会当。这是一个方式。还有,你说可以在while里面把buffer里的内容读走,再把is_full的值改了,但是我们会可能把重 要的数据在我们不想被读的时候被读走了,那是比较麻烦的,而且很不灵活.如果我们使用 wait_queue 的话, 那程序看起来会比较漂亮,而且也比较让人了解,如下所示:
 
struct wait_queue_head_t wq; /* global variable */
DECLARE_WAIT_QUEUE_HEAD (wq);
 
while ( is_full ){
interruptible_sleep_on( &wq );
} write_to_buffer();
 

interruptible_sleep_on( &wq ) 是用来将目前的 process,也就是要求写资料到buffer 的 process放到 wq 这个 wait_queue 里。在 interruptible_sleep_on 里,则是最后会呼叫 schedule() 来做 schedule 的动作,谁调用了schedule谁就趴下,让别人去运行,醒来就原地起来,执行schedule()后的代码。那那个调用了schedule的家伙什么 醒过来呢?这时候就需要用到另一个函数了wake_up_interruptible()了。

 

以下来自:http://tauruspdj.blog.163.com/blog/static/4312500620090794030998/

linux中最简单的休眠方式是下面的宏, 
wait_event(queue, condition)  /* 进程将被置于非中断休眠(uninterruptible sleep)*/
wait_event_interruptible(queue, condition) /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/
wait_event_timeout(queue, condition, timeout)    /*等待限定时间jiffy,condition满足其一返回0*/ 
wait_event_interruptible_timeout(queue, condition, timeout) 
queue是等待队列头,传值方式
condition是任意一个布尔表达式,在休眠前后多次对condition求值,为真则唤醒

唤醒进程的基本函数是wake_up
void wake_up(wait_queue_head_t *queue);     /*唤醒等待在给定queue上的所有进程*/
void wake_up_interruptible(wait_queue_head_t *queue); 

实践中,一般是wait_event和 wake_up, wait_event_interruptible和 wake_up_interruptible 成对使用。

 

【补充】其实看了那么多,他们也没有给个立即可用的步骤,写blog嘛,就是分享心得。我基于2.6.24总结一下,希望对大家有帮助:

1、定义:wait_queue_head_t my_queue;

2、初始化 init_waitqueue_head(&my_queue);

3、在一个函数里面等待:wait_event(queue, condition) ;(别在中断里面搞)

4、在另一个函数里面唤醒:wake_up(wait_queue_head_t *queue); (这个可以在中断调用,去唤醒别的进程,特别是dma操作类的)

有好几个等待和唤醒函数,大家可以慢慢试。

相关文章推荐

linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠

以下来自:http://www.yuanma.org/data/2006/1207/article_1916.htm 假设我们在 kernel 里产生一个 buffer,user 可以经由read,...

等待队列wait_queue_head_t使用

当你在用户空间需要读写一大片数据的时候,这个就用上了。 以下来自:http://www.yuanma.org/data/2006/1207/article_1916.htm 假设我们在 k...

31 completion完成量,wait_queue_head_t等待队列和epoll

完成量, 功能与信号量差不多, 最大不同可以唤醒多个休眠的进程或线程#include struct completion { unsigned int done; //done表示资源,上锁...
  • jklinux
  • jklinux
  • 2017年06月13日 10:50
  • 343

Linux等待队列wait_queue_head_t和wait_queue_t

Linux等待队列wait_queue_head_t和wait_queue_t

linux等待队列wait_queue_head_t和wait_queue_t

等待队列在linux内核中有着举足轻重的作用,很多linux驱动都或多或少涉及到了等待队列。因此,对于linux内核及驱动开发者来说,掌握等待队列是必须课之一。 Linux内核的等待队列是以双循环链表...

信号量和队列:semaphore and wait_queue_head_t

这一次是在globalmem的字符设备驱动的基础上,增加了并发控制(也就是多进程多共享资源的访问的控制),还增加了阻塞I/O 和poll轮询操作,因为我还是菜鸟,有很多东西还不懂,希望与大侠能指点学习...

Linux内核wait_queue深入分析

http://user.qzone.qq.com/120464685/blog/1321571776   Linux内核wait_queue深入分析   前几天在看驱动...
  • HEN_MAN
  • HEN_MAN
  • 2011年11月18日 09:36
  • 427

Linux内核中的等待队列--init_waitqueue_head等

Linux内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。在Linux2.4.21中,等待队列在源代码树include/linux/wait.h...

Linux内核中的等待队列--init_waitqueue_head

Linux内核中的等待队列     Linux内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。在Linux2.4.21中,等待队列在源代码树i...

linux内核中等待队列(wait_event,wake_up...)

2012-12-25 15:09:57 分类: LINUX 根据内核3.1.6版本源码、书籍和网上资料,对几个函数进行分析        介绍这几个函数,不得不先介绍...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠
举报原因:
原因补充:

(最多只允许输入30个字)