3

所以,问题是:我正在为我的大学项目编写一个“聊天模拟器”。不谈太多细节,客户端可以运行多次,所有实例都使用由信号量保护的同一段共享内存(除其他外)。

客户端在未知时间进出系统。当第一个客户端进入系统时,它应该创建一个信号量,使用共享内存并释放。但是,如果任何其他客户端进入系统,它必须在获取共享内存访问之前等待信号量。

现在,我觉得我遗漏了一些明显的东西——如何初始化信号量?如果我使用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,请求将失败,但我不知道下一步该怎么做。

4

2 回答 2

3

您可以执行以下操作:

  1. 打电话semget(key, nsems, IPC_CREAT | IPC_EXCL)。如果这成功了,您现在已经创建了一个新的信号量集,然后您应该通过semctl()
  2. 如果之前semget()失败,请semget()再次调用,不带IPC_EXCL标志。

我还建议使用锁定文件(通过flock()或类似方式)以确保在初始化之前不使用信号量集。

于 2013-02-20T17:44:38.383 回答
0

我认为信号量的所有用户都需要获得它已经初始化。否则,信号量本身的初始化会受到竞争条件的影响。你可以有一个守护进程在系统引导时初始化信号量并照顾

create_sem;
raise_sem;

而客户只是执行

get_sem_handle;
于 2013-02-20T16:12:48.100 回答