【问题标题】:semget: how to avoid concurrent access to semaphore group on its creating/initialization?semget:如何避免在创建/初始化时同时访问信号量组?
【发布时间】:2017-03-17 07:12:07
【问题描述】:

当我使用 semget 创建信号量组 id(传递 IPC_CREAT | IPC_EXCL 标志)时 - 一般情况下,我在组内的信号量未初始化并且可能包含“随机值”。

所以我需要在获得新创建的信号量组的 id 后立即初始化所有信号量。

我的问题是:

如何避免semgrpID=semget(semgrpKey,nSemaphores,IPC_CREAT | IPC_EXCL); 之间的潜在竞争条件 和 semctl(semgrpID,0,SETALL,...); ?

【问题讨论】:

  • 创建信号量的进程需要在创建任何使用信号量的进程之前完成初始化。处理此问题的典型方法是创建/初始化信号量,然后分叉/执行其他进程。
  • 访问这个信号量组的进程可以从 crond、CLI 开始,并且可以从 webserver 初始化。它不是从一个单一进程派生出来的。所以我需要保护信号量组本身,但为此我需要......信号量在某个地方?
  • 然后作为启动序列的一部分,您需要运行一个程序来创建和初始化信号量组。它必须在任何使用信号量的程序被允许启动之前完成。
  • 或者我可以在添加信号量组时使用flock,但我完全使用信号量组以避免使用任何flock。嗯...我希望,使用一个羊群而不是 10 个(已被信号量取代) - 是一个很好的折衷方案。
  • 我想,我知道我的问题的答案。它是:“不要使用旧的 semget/semop/semctl”,而是使用 POSIX 信号量。 POSIX 的函数 sem_open 支持在一个原子操作中创建+初始化。

标签: c perl unix ipc semaphore


【解决方案1】:

考虑使用 POSIX 信号量而不是 SYSV 信号量。 POSIX设计更简单更干净;例如,POSIX 信号量是使用指定的初始值创建的。

但是,SYSV 信号量确实具有一些 POSIX 信号量不具备的功能,例如可撤消的操作和使用多元素信号量sets。如果您必须使用 SYSV 风格,那么 ...

我想您想为信号量集使用一个众所周知的键,这样您就无法控制除了指定用于创建信号量集的进程访问该集的时间。在最坏的情况下,您可能有多个进程都试图通过相同的键和IPC_CREAT | IPC_EXCL 设置信号量,成功的进程负责初始化,而那些得到EEXIST 的进程在没有这些标志的情况下再次尝试.确实,这确实会造成混乱。

如果您遇到不相关的进程使用众所周知的信号量集键的情况,则关联的信号量集是系统资源,不属于任何单独的进程。在这种情况下,您应该有专门用于初始化和管理它的程序。这些应该连接到您的系统初始化框架。

也可以使用其他形式的互斥来保护信号量集的初始化。例如,您可能会使用锁定文件。您甚至可以将 POSIX 信号量用于这个有限的目的。

【讨论】:

  • 非常感谢,这正是我想知道的!
猜你喜欢
  • 1970-01-01
  • 2016-07-31
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多