我使用命名的System V信号量来锁定OSX和Linux上的所有应用程序中的文件。根据任何定义,不是最漂亮的API。正确销毁命名的系统V信号量
它似乎工作,但我不能完全弄清楚如何在每个人都完成后正确地销毁信号量。
通用逻辑是这样的:
创建:
[1]的线程或进程试图打开信号量与()由ftok为文件创建的key_t设置。 Set包含2个信号量。 [2]如果信号量集不存在,它将创建666个权限。 [3]“锁定”(其中一个信号)设置为释放状态(值1)。 [4]“引用计数”(同一组中的另一个信号量)递增。
锁定/解锁:
要锁定[5],线程减1,“锁定”信号量的值(具有撤销),从而等待如果它已经为零。要解锁[6],线程会将其加1,从而允许别人锁定它。
毁:
[7] “引用计数” 信号被试图递减(用IPC_NOWAIT标志)。 [8]它的值被检查为0,并且如果它是[9]信号集被销毁。
(也有基于线程本地存储逻辑层,使一个线程内锁递归)
的问题是:
- 如何同步步骤[1] [2]? (如果信号集不存在,但是当我们计算星星时,它是由其他人创建的,所以现在创建也将失败)
- 如何将步骤[4]与[8]同步以便[9]执行不是过早地杀了我?
- 有没有其他的比赛条件?
PS:虽然POSIX信号有更漂亮的API,我不认为我能活下来sem_inlink()行为如下所述:
呼叫至sem_open()来重新创建或重新 - 连接到信号量是指在调用sem_unlink()后 之后的新信号量 。
所以我没有办法释放他们...
我不知道致命的缺陷:信号量的创造是原子的(我希望?)。下一个进程会实际得到它,或者最坏的情况是无法创建一个调用(应该简单地尝试在循环中再次获取它)。然后,直到创建过程释放它(设置为1),其他人将已经存在的sem,并且如果试图“锁定”(用-1),他们将等待。创建过程失去控制,但没关系,它们都是平等的。 – Eugene 2009-08-07 04:57:58
(其实这就回答我的一个问题,我只是不想循环:)) – Eugene 2009-08-07 05:01:54
至于保持一个sem,在linux上最大一般很小,比如128集。我只需要锁定几个文件,但是我的单元测试速度非常快 - 这是我不想使用的主要原因。 – Eugene 2009-08-07 05:07:57