关于等待队列


通常来讲,当读取,一个设备时,没有可读数据,可以阻塞该读进程,等待写进程写入数据。Linux提供了等待队列来维护一些阻塞(休眠)进程。

等待队列就是一个进程链表,包含了等待某个特定事件的所有进程。等待队列三通过一个等待队列头来管理这个队列的。这个头类型为:wait_queque_head_t,定义在<linux/wait.h>。可以通过下面的宏来初始化一个等待队列头:

       DECLARE_WAIT_QUEQUE_HEAD(name);

也可以动态的定义一个等待队列头:

       wait_queue_head_tmy_queue;

      init_waitqueue_head(&my_queue);

有了头以后,也就是说我们已经用有了一个等待队列,还缺少关于等待队列的entry了。下面我们要初始化一个等待队列entry:

       DEFINE_WAIT(my_wait);

或者用动态的方式:

       wait_queue_tmy_wait;

      init_wait(&my_wait);

接下来,我们要把这个entyr加到等待队列中去,并且设置进程的状态。prepare_to_wait帮助我们完成这项任务。

       voidprepare_to_wait(wait_queue_head_t *queue,wait_queue_t *wait,int state);

到了这步后,我们可以执行schedule();来调度进程了。当schedule返回了,可以调用finish_wait()来把作清除工作了。finish_wait原型:

       voidfinish_wait(wait_queue_head_t *queue,wait_queue_t *wait);

执行调度后,也就宣告我们把一个进程放到了等待队列上了,这个entry会等待我们去唤醒它。关于唤醒函数,是有几个变种的,下面尽量概括齐全。

       wake_up(wait_queue_head_t*queue);//唤醒等待队列上非独占等待的进程

       wake_up_interruptible(wait_queue_head_t*queue);//唤醒等待队列上可中断的等待进程

       wake_up_nr(wait_queue_head_t*queue,int nr);//唤醒等待队列上的nr个进程

       wake_up_interruptible_nr(wait_queue_head_t*queue,int nr);// 唤醒等待队列上可中断的nr个等待进程(当nr为0,表示唤醒所有)

       wake_up_all(wait_queue_head_t*queue);//唤醒所有进程,无论是否为独占等待

       wake_up_interruptible_all(wait_queue_head_t*queue);//唤醒所有可中断进程,无论是否为独占等待

       wake_up_interruptible_sync(wait_queue_head_t*queue);//在唤醒进程的同时,强制重新调度

对于上面几个唤醒函数,一般也就用到wake_up_interruptible()。

假设有一个读进程,一个写进程。等待队列在程序代码的实现一般如下:

       int XXX_read(…)

      {

           wait_queue_head_t my_queue;

           wait_queue_t my_wait;

           init_waitqueue_head(&my_queue);

           init_wait(&my_wait);

           prepare_to_wait(&my_queue,&my_wait,TASK_INTERRUPTIBLE);

           if(STATE_EMPTY)

                 schedule();

           finish_wait(&my_queue);

      }

 

      int XXX_write()

      {

           if(!STATE_EMPTY)

                 wake_up_interruptible(&my_queue);

      }

大概就是这样一个思路,数据空时(STATE_EMPTY为真),让读进程进入等待队列。数据非空时,唤醒等待队列,schedule返回,接着执行读进程。具体的细节,自己琢摩去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值