2012-04-18 25 views
5

所以,如果我有一个信号灯设置semidnum_of_sems信号灯和sembuf*deleter_searchers_downSemop:减少一组信号量时是立即减少还是在第一次失败时阻塞?

struct sembuf *deleter_searchers_down 
         = malloc(sizeof (*deleter_searchers_down) * num_of_sems); 
for (i = 0; i < num_of_sems; ++i) { 
      (deleter_searchers_down + i)->sem_op = -1; 
      (deleter_searchers_down + i)->sem_num = i; 
      (deleter_searchers_down + i)->sem_flg = SEM_UNDO; 
     } 
semop(semid, deleter_searchers_down, num_of_sems); 

到SEMOP将尝试一次降低集合中的所有信号量还是会阻止一次它试图调用降低第一个信号量是0,并继续其他一些进程后,特定的信号量?

+0

好的信号量完全符合你说的,也就是说,当它们被降低时,如果它们是0,它们会阻止该过程。 – byrondrossos 2012-04-18 09:33:02

+0

仔细阅读这个问题plz - 将semop试图降低所有的零和所有的块,或将它阻止遇到的第一个(第一个?)0 – 2012-04-18 09:35:17

+0

您可以指定IPC_NOWAIT立即返回失败。请参阅:http://pubs.opengroup.org/onlinepubs/7908799/xsh/semop.html – RedX 2012-04-18 09:53:30

回答

6

只有当所有更新都可以作为一个单元进行时,才会有更新。

虽然POSIX规范说semop是原子的,但POSIX规范可能会更清晰。

在Linux上,glibc中的semop(3)是一个围绕semop(2)的简单包装。该semop(2)手册页反过来说

该组包含在sops操作在阵列顺序,和原子进行,即,操作被执行或者作为一个完整的单元,或根本没有。

的HP-UX semop(2)手册页是更清楚:

旗语 阵列操作是在没有信号灯操作 ,直到在 阵列上的所有的信号量的阻断条件下进行的原子已被删除。

+0

谢谢 - 这是否意味着尝试向下semid的进程将阻塞第一个数组元素为0,semop()将撤消所有先前的数组元素downs()? – 2012-04-18 13:16:51

+0

这取决于实施。例如,Linux ipc/sem.c(函数'try_atomic_semop')中的代码与您描述的类似。它会尝试操作,如果其中任何一个被阻止,则更改将被撤消。但有一点很重要:更新是在锁定信号集的同时完成的。所以不一致的状态对任何其他任务都是不可见的:一个希望改变信号量的任务首先必须获得该锁,而在信号量上阻塞的任务已经睡着了。所以最后这个操作是真正的原子。 – 2012-04-18 17:07:59

+0

好的 - 谢谢 - 最后一点:没有机会(实现)调用semop的进程将阻塞_all_信号量为0? – 2012-04-18 17:35:27