免费注册 查看新帖 |

Chinaunix

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

[内核同步] 内核信号量问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-03-29 19:49 |只看该作者 |倒序浏览
今天看linux的内核信号量,有个问题没搞懂,求助大神!
书上说的up( )函数释放信号量的代码:
movl $sem->count,%ecx
lock; incl(%ecx)
jg 1f
lea %ecx,%eax
pushl %edx
pushl %ecx
call __up
popl %ecx
popl %edx
__up( )c函数:
  __attribute__((regparm(3))) void __up(struct semaphore *sem)
{
wake_up(&sem->wait);
}
获取信号量的down函数代码
down:
         movl $sem->count,%ecx
         lock;decl (%ecx)
         jns 1f
        lea %ecx,%eax
       pushl %edx
      pushl %ecx
      call __down
      popl %ecx
      popl  %edx
1:
__down函数的实现如下:
fastcall void __sched __down(struct semaphore * sem)
{
        struct task_struct *tsk = current;
        DECLARE_WAITQUEUE(wait, tsk);
        unsigned long flags;

        tsk->state = TASK_UNINTERRUPTIBLE;
        spin_lock_irqsave(&sem->wait.lock, flags);
        add_wait_queue_exclusive_locked(&sem->wait, &wait);

        sem->sleepers++;
        for (; {
                int sleepers = sem->sleepers;

                /*
                 * Add "everybody else" into it. They aren't
                 * playing, because we own the spinlock in
                 * the wait_queue_head.
                 */
                if (!atomic_add_negative(sleepers - 1, &sem->count)) {         //这一条语句*
                        sem->sleepers = 0;
                        break;
                }
                sem->sleepers = 1;        /* us - see -1 above */
                spin_unlock_irqrestore(&sem->wait.lock, flags);

                schedule();

                spin_lock_irqsave(&sem->wait.lock, flags);
                tsk->state = TASK_UNINTERRUPTIBLE;
        }
        remove_wait_queue_locked(&sem->wait, &wait);
        wake_up_locked(&sem->wait);
        spin_unlock_irqrestore(&sem->wait.lock, flags);
        tsk->state = TASK_RUNNING;
}

假设此时有5个线程阻塞在信号量上,此时sem->count=-5,那么当有一个线程调用up()释放了信号量**了一个阻塞的线程,那么按照以上*号语句处的条件这个被**的线程还是要被挂起,这里是怎么一回事儿?求助.

论坛徽章:
0
2 [报告]
发表于 2014-03-29 19:53 |只看该作者
**是huan,醒

论坛徽章:
0
3 [报告]
发表于 2014-04-01 18:29 |只看该作者
搞错了,sem->count为正数表示还有多少资源可用,为0表示资源正忙,为负数,这里的负数用来表示有进程在等待的时候,只是用-1表示有,并不是用负数的大小表示等待资源的进程数目,信号量没必要记录等待资源的进程数目。所以程序执行完这里时
if (!atomic_add_negative(sleepers - 1, &sem->count)) {         //这一条语句*
                        sem->sleepers = 0;
                        break;
                }
后sem->count的值只有0或者-1;
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP