免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6081 | 回复: 11
打印 上一主题 下一主题

linux的进程等待队列有几个 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-08 20:24 |只看该作者 |倒序浏览
有一个还是根据不同的事件类型分为多个??

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2011-10-08 22:03 |只看该作者
根据不同的事件类型

论坛徽章:
0
3 [报告]
发表于 2011-10-08 22:09 |只看该作者
根据等待不同的事件类型分成多个,比如jbd中等待数据写入完成,还有sched中等待时间经过固定的间隔,都会使用各种wait queue.

论坛徽章:
0
4 [报告]
发表于 2011-10-09 08:17 |只看该作者
根据等待不同的事件类型分成多个,比如jbd中等待数据写入完成,还有sched中等待时间经过固定的间隔,都会使 ...
SharkBones 发表于 2011-10-08 22:09


    那么当某个事件的等待队列的条件到达时,所有的进程都被移动到可执行队列,然后调度程序选择一个进程投入运行(优先级高的话),其余的又回到刚才的等待队列,
是这样的过程吗,如果是这样,效率是不是很低呢

论坛徽章:
0
5 [报告]
发表于 2011-10-09 21:50 |只看该作者
基本上如此,但内核将唤醒后没有被执行的进程仍然放置在runqueue中,而不是放回原来的等待队列。
waitqueue的设计目的就是为了处理无法预知等待时间而必须等待的情况, 将这种类型的进程放置在等待队列中,
进而让出cpu让其他进程执行。对于等待时间较短的使用spin lock更合适。

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
6 [报告]
发表于 2011-10-13 10:10 |只看该作者
基本上如此,但内核将唤醒后没有被执行的进程仍然放置在runqueue中,而不是放回原来的等待队列。
waitqueu ...
SharkBones 发表于 2011-10-09 21:50



   请教“仍然放置在runqueue”是怎么看出来的,如果只有一个进程获得资源,其他进程应该回去继续睡眠才对。为了解决kkmm0105兄说的这个效率很低问题,kernel中引入了互斥进程和非互斥进程。互斥进程由内核有选择的唤醒,而非互斥进程由内核在事件发生时唤醒。在将进程添加到等待队列的时候可以进行设置的,add_wait_queue(),add_wait_queue_exclusive(),prepare_to_wait(),prepare_to_wait_exclusive()。

论坛徽章:
0
7 [报告]
发表于 2011-10-14 16:58 |只看该作者
本帖最后由 SharkBones 于 2011-10-14 17:00 编辑

回复 6# embeddedlwp
是我描述的不清楚,应该这样描述:已经加入runqueue的进程不会再被放回等待队列,而原来就在等待队列中没有被唤醒的进程则依然在队列中。
可以从代码中看出来,在include/linux/wait.h中:
  1. #define __WAITQUEUE_INITIALIZER(name, tsk) {                                \
  2.         .private        = tsk,                                                \
  3.         .func                = default_wake_function,                        \
  4.         .task_list        = { NULL, NULL } }

  5. #define DECLARE_WAITQUEUE(name, tsk)                                        \
  6.         wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)   
复制代码
default_wake_function定义在kernel/sched.c中,如下:
  1. int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
  2.                           void *key)
  3. {
  4.         return try_to_wake_up(curr->private, mode, wake_flags);
  5. }
复制代码
调用了tyr_to_wake_up,
  1. static int try_to_wake_up(struct task_struct *p, unsigned int state,
  2.                           int wake_flags)
  3. {
  4.         int cpu, orig_cpu, this_cpu, success = 0;
  5.         unsigned long flags;
  6.         struct rq *rq, *orig_rq;
  7. ...
  8.         if (cpu == this_cpu)
  9.                 schedstat_inc(p, se.nr_wakeups_local);
  10.         else
  11.                 schedstat_inc(p, se.nr_wakeups_remote);
  12.         activate_task(rq, p, 1);
  13.         success = 1
  14. ...
复制代码
active_task将一个task放置于runqueue中,然后调用schedule,最终调用_ _remove_wait_queue()把该task从等待队列中移除。
另一方面,wake_up调用了__wake_up_common函数,
  1. static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
  2.                         int nr_exclusive, int wake_flags, void *key)
  3. {
  4.         wait_queue_t *curr, *next;

  5.         list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
  6.                 unsigned flags = curr->flags;

  7.                 if (curr->func(curr, mode, wake_flags, key) &&
  8.                                 (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
  9.                         break;
  10.         }
  11. }
复制代码
可以看到curr->func调用的就是default_wake_function,nr_exclusive减为0的时候就不在唤醒等待队列中的task了。

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
8 [报告]
发表于 2011-10-14 18:11 |只看该作者
回复 7# SharkBones


    确实是这样,不过在调用wake_up_all()的时候会唤醒等待队列上的所有进程,所有进程都会调用tyr_to_wake_up(),可是有时只能有一个进程得到资源,其他进程重新回去睡眠,我怎么没有找到对是否获得资源检查,没获得的回去睡眠的代码阿,请指点!

论坛徽章:
0
9 [报告]
发表于 2011-10-14 22:00 |只看该作者
wake_up_all函数顾名思义就是将所有的进程唤醒,并重新放置在相应的runqueue中,此时waitqueue中已经没有等待的进程了。如果某个进程被调度执行后,其他进程得不到相应的资源,就会重新进入等待队列进而睡眠。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2011-10-14 23:13 |只看该作者
9楼说得没错,进程在醒后是会检查的.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP