2012-07-29 17 views
2

在我的代码做以下初始化:当两个进程试图访问信号量为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()调用多个进程(注意)。

谢谢

+0

您正在调用'fork()'两次:一次在开始时,一次在if条件时 – knittl 2012-07-29 09:19:28

+0

@knittl:好的,那有什么问题?这是有意地完成的 – ron 2012-07-29 09:20:05

+1

你最后有4个进程(父和子都是fork())。来自第二个分支('if(fork())')的进程将分别具有原始信号量的独特副本。 – knittl 2012-07-29 09:22:01

回答

1

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

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

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

编辑您的编辑后:没有它不会像这样工作。您必须将整个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的名称轻松使用。
+0

我已经这样做了,它仍然继续。请参阅编辑后的结构修改。我在'H'文件中创建了结构体,并将其初始化为'C'文件 – ron 2012-07-29 11:01:07

+0

请注意,我还添加了新的结构体......谢谢! – ron 2012-07-29 13:20:33

+0

但我在我的代码中使用了'sem_wait()',它的原型是'int sem_wait(sem_t * sem);'它得到一个指针作为参数... – ron 2012-07-30 20:48:58

相关问题