免费注册 查看新帖 |

Chinaunix

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

[内核同步] 信号量(semaphore)中的sleepers字段 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-21 10:54 |只看该作者 |倒序浏览
本帖最后由 sygspjlsj 于 2012-05-21 10:57 编辑

小弟最近在看《深入理解linux内核》内核同步那章,讲到信号量semaphore,
其中有一个字段是sleepers,网上有的说是等待信号量的进程的数量,但书上
说的比较好,是一个标志,通过分析源码我感觉说是一个标志比较合适。
上源码:
  1. fastcall void __sched __down(struct semaphore * sem)
  2. {
  3.         struct task_struct *tsk = current;
  4.         DECLARE_WAITQUEUE(wait, tsk);
  5.         unsigned long flags;

  6.         tsk->state = TASK_UNINTERRUPTIBLE;
  7.         spin_lock_irqsave(&sem->wait.lock, flags);
  8.         add_wait_queue_exclusive_locked(&sem->wait, &wait);//把进程加到等待队列

  9.         sem->sleepers++;//等待队列标志
  10.         for (;;) {
  11.                 int sleepers = sem->sleepers;

  12.                 /*
  13.                  * Add "everybody else" into it. They aren't
  14.                  * playing, because we own the spinlock in
  15.                  * the wait_queue_head.
  16.                  */
  17.                           //count>=0,置sleepers=0,退出循环,唤醒进程
  18.                  //否则,执行后面的代码
  19.                 if (!atomic_add_negative(sleepers - 1, &sem->count)) {
  20.                         sem->sleepers = 0;
  21.                         break;
  22.                 }
  23.                 sem->sleepers = 1;        /* us - see -1 above */
  24.                 spin_unlock_irqrestore(&sem->wait.lock, flags);

  25.                 schedule();

  26.                 spin_lock_irqsave(&sem->wait.lock, flags);
  27.                 tsk->state = TASK_UNINTERRUPTIBLE;
  28.         }
  29.         remove_wait_queue_locked(&sem->wait, &wait);
  30.         wake_up_locked(&sem->wait);
  31.         spin_unlock_irqrestore(&sem->wait.lock, flags);
  32.         tsk->state = TASK_RUNNING;
  33. }
复制代码
信号量初始化count=1,sleepers=0
假设进程A开始申请资源,则count变为0,开始使用资源
进程B接着申请资源,(假设A还没释放)count变为-1,进入__down()函数,sleepers变为1,执行schedule。
进程C接着申请资源,(假设B还在睡眠,刚刚schedule上的进程还在执行),count变为-2,sleepers变为2(sem->sleepers++),进入循环之后
      sleepers又变为1,但现在睡眠的有两个进程。所以我感觉sleepers解释为标志更合理些。
关于这个问题,不知道哪位大锅有更好的见解,或者关于关于这一块有别的想法。
我感觉这块不同的执行顺序可以分很多种情况,很复杂!
期待ing

论坛徽章:
0
2 [报告]
发表于 2012-05-21 15:37 |只看该作者
肿膜没有人回答呢,难道俺的问题太rz。。。。。

论坛徽章:
0
3 [报告]
发表于 2012-05-21 16:18 |只看该作者
你也没问问题啊
而且最新代码里,semaphore的实现方式已经修改了

论坛徽章:
0
4 [报告]
发表于 2012-05-21 22:36 |只看该作者
回复 3# senioryzc
这部分看的不是很深,实在问不出问题来,晚上跟同学聊了下,我上面的理解应该是没问题的。
另外,最新的代码也是建立在旧版本的基础上的,先弄懂老的,再弄新的,嘿嘿。


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP