当两个进程尝试访问信号量为0的关键部分时会发生什么?

在我的代码中,我做了以下初始化:

struct PipeShm myPipe = { .init = 0 , .flag = FALSE , .mutex = NULL , .ptr1 = NULL , .ptr2 = NULL , .status1 = -10 , .status2 = -10 , .semaphoreFlag = FALSE }; int initPipe() { if (!myPipe.init) { myPipe.mutex = mmap (NULL, sizeof *myPipe.mutex, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (!sem_init (myPipe.mutex, 1, 0)) // semaphore is initialized to 0 { myPipe.init = TRUE; } else perror ("initPipe"); } return 1; // always successful } 

我可以有多个可以从main()调用的进程(注意fork )。

谢谢

Solutions Collecting From Web of "当两个进程尝试访问信号量为0的关键部分时会发生什么?"

AFAICS你的错误是在你的控制变量。 只有你的mutex变量是在进程之间共享的,而不是你的initflag变量。 这些都是写入的副本,所以你不会看到在不同的过程中的变化。

您必须将所有控制变量打包到您创建的段中。 为您需要的所有字段创建适当的struct类型。

顺便说一句,调用信号量mutex是一个坏主意。 互斥体具有与信号量完全不同的语义。 (或者如果你真的使用它作为一个互斥体,我没有检查,在初始化程序中用pshared使用pthread_mutex_t 。)

编辑后编辑:不,它不会像这样工作。 你真的必须把整个struct放在共享段中。 所以你的struct PipeShm必须包含一个sem_t sem而不是sem_t* mutex 。 那么你会做类似的事情

 struct PipeShm * myPipe = 0; int initPipe() { if (!myPipe->init) { myPipe = mmap (NULL, sizeof *myPipe, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (!sem_init (myPipe->sem, 1, 0)) // semaphore is initialized to 0 { myPipe->init = true; } else perror ("initPipe"); } return 1; // always successful } 

其他事情你应该知道:

  • sem_t接口可以被任何类型的IO或其他信号中断。 您必须检查这些功能的返回情况,尤其是在收到EINTR重新启动功能。
  • Mondern C有一个布尔值。 这可以通过包含<stdbool.h>通过boolfalsetrue名称轻松使用。