2012-07-29 49 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

相關問題