2011-07-28 123 views
3

根據我的理解,信號量應該可以在相關進程中使用,而不必將其放置在共享內存中。如果是這樣,爲什麼下面的代碼會死鎖?瞭解posix進程間信號量

#include <iostream> 
#include <semaphore.h> 
#include <sys/wait.h> 

using namespace std; 

static int MAX = 100; 

int main(int argc, char* argv[]) { 
    int retval; 
    sem_t mutex; 

    cout << sem_init(&mutex, 1, 0) << endl; 

    pid_t pid = fork(); 

    if (0 == pid) { 
    //  sem_wait(&mutex); 
    cout << endl; 
    for (int i = 0; i < MAX; i++) { 
     cout << i << ","; 
    } 
    cout << endl; 
    sem_post(&mutex); 

    } else if(pid > 0) { 
    sem_wait(&mutex); 
    cout << endl; 
    for (int i = 0; i < MAX; i++) { 
     cout << i << ","; 
    } 
    cout << endl; 
    //  sem_post(&mutex); 
    wait(&retval); 

    } else { 
    cerr << "fork error" << endl; 
    return 1; 
    } 

// sem_destroy(&mutex); 

    return 0; 
} 

當我在Gentoo/Ubuntu Linux上運行這個時,父節點掛起。顯然,它沒有收到兒童的帖子。取消註釋sem_destroy不會有任何好處。我錯過了什麼嗎?

更新1: 此代碼的工作

mutex = (sem_t *) mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); 
if (!mutex) { 
    perror("out of memory\n"); 
    exit(1); 
} 

感謝, Nilesh製作。

+0

您可以爲您正在使用的語言添加標籤嗎?我會猜c或C++,但它會有助於可擴展性。 – NickHeidke

回答

4

the manual page的措辭有點含糊不清。

如果的pshared爲非零,則信號量進程之間共享, 和應位於共享存儲器的區域。

由於由fork(2)創建的子級繼承其父級的內存 映射,因此它也可以訪問信號量。

是的,但是它仍然必須在共享區域。否則,內存只需使用通常的CoW進行復制,就是這樣。

可以在至少兩種方式解決這個問題:

  • 使用sem_open("my_sem", ...)
  • 使用shm_openmmap創建一個共享區域
+0

感謝您的回覆!這是我沒有成功的嘗試......((mutex = sem_open(「mysemaphore」,O_CREAT,0644,0))== SEM_FAILED){ \t cerr <<「semaphore initilization error」<< endl; \t return 1; } pid_t pid = fork(); 如果(0 == PID){ \t/* \t如果((互斥= sem_open( 「mysemaphore」,0,0644,0))== SEM_FAILED){ \t CERR << 「旗語動初始化錯誤」< 0){ \t sem_wait(mutex); \t cout <<「here2」<< endl; \t wait(&retval); } 輸出: here2 here1 – Nilesh

+0

確認!格式化在評論中混亂了,不知道如何解決這個問題。 – Nilesh

+2

而不是一個命名的信號量,我會'mmap'匿名共享內存和它處理的'sem_init' - 在分叉之前共享。這樣你就不必擔心離開你必須清理的命名資源。 –