我正在使用命名的 System V 信号量来锁定我在 OSX 和 linux 上的所有应用程序中的文件。无论如何定义都不是最漂亮的 API。
它似乎有效,但我不太清楚在每个人都完成后如何正确销毁信号量。
一般逻辑是这样的:
创建:
[1] 线程或进程尝试使用 ftok() 为文件创建的 key_t 打开一个信号量集。Set 包含 2 个信号量。[2] 如果信号量集不存在,则使用 666 权限创建。[3] “锁定”(信号量之一)设置为释放状态(值 1)。[4] “引用计数”(同一集合中的另一个信号量)递增。
锁定/解锁:
要锁定 [5],线程将“Lock”信号量的值减 1(撤消),因此如果它已经为零,则等待。为了解锁 [6],线程将其加一,从而允许其他人锁定它。
销毁:
[7] 尝试减少“引用计数”信号量(使用 IPC_NOWAIT 标志)。[8] 检查其值为0,如果为[9],则销毁信号量集。
(还有一层基于线程本地存储的逻辑,使锁在一个线程内递归。)
问题是:
- 如何同步步骤 [1] 和 [2]?(如果信号量集不存在,但是当我们计算星星时,它是由其他人创建的,所以现在创建也会失败)
- 如何将步骤 [4] 与 [8] 同步,以便 [9] 不会过早杀死我?
- 还有其他比赛条件吗?
PS:虽然 POSIX 信号量有更好的 API,但我认为我无法在此处描述的 sem_inlink() 行为中幸存下来:
调用 sem_open() 以重新创建或重新连接到信号量是指调用 sem_unlink() 后的新信号量。
所以我没有办法释放他们......