所以,问题是:我正在为我的大学项目写一个“聊天模拟器”。没有深入细节,客户端可以多次运行,并且所有实例都使用由信号量保护的相同内存共享内存段(以及其他内容)。
客户在未知时间进入和退出系统。当第一个客户端进入系统时,它应该创建一个信号量,使用共享内存并释放。但是,如果任何其他客户端进入系统,它必须在获取共享内存访问权限之前等待信号量。
现在,我觉得我错过了一些明显的东西 - 如何初始化信号量?如果我使用semget(42, 1, IPC_CREAT)
,产生的信号量很可能是0 - 但是我无法提升它以初始化它,因为0可能意味着临界区中已经有一个进程。换句话说,我不知道我是否刚刚创建了默认值为0的信号量,或者是否有一个进程正在等待信号量。
在伪代码中:
if(semaphore_not_exists(42))
{
create_sem;
raise_sem;
}
else
{
get_sem_handle;
}
wait_on_sem;
critical_section;
release_sem;
那么,我如何确保信号量尚未由另一个进程创建,以便初始化它是安全的?如果我使用IPC_EXCL
,请求将失败,但我不知道接下来应该做什么。
答案 0 :(得分:2)
您可以执行以下操作:
semget(key, nsems, IPC_CREAT | IPC_EXCL)
。如果成功,您现在已经创建了一个新的信号量集,然后您应该通过semctl()
设置semget()
失败,请再次致电semget()
,不要使用IPC_EXCL
标记。我还建议使用锁文件(通过flock()
或类似方法)以确保在初始化之前不使用信号量集。
答案 1 :(得分:0)
我认为信号量的所有用户都需要获取它已经初始化。否则,信号量本身的初始化受竞争条件的影响。 你可以有一个守护进程,它在系统引导程序初始化信号量并处理
create_sem;
raise_sem;
而客户只是执行
get_sem_handle;