2011-07-28 12 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でコピーされます。

あなたは、少なくとも2つの方法でこの問題を解決することができます。

  • 使用sem_open("my_sem", ...)
  • 使用shm_openmmap共有領域を作成するための
+0

お返事ありがとうございます!ここで私は成功なしで試したものです... ((ミューテックス= sem_open( "mysemaphore"、O_CREAT、0644、0))== SEM_FAILED){ \t CERR << "セマフォinitilizationエラー" << ENDL場合、 \t return 1; } pid_t pid = fork(); (0 ==のPID){ \t/* \t IF((ミューテックス= sem_open( "mysemaphore"、0、0644、0))== SEM_FAILED){ \t CERR << "セマフォinitilizationエラー" < 0){ \t sem_wait(mutex); \tcout << "here2" << endl; \t待機(&retval); } 出力: here2 here1 – Nilesh

+0

Ackを!書式設定がコメントに混乱している、それを修正する方法がわからない。 – Nilesh

+2

名前付きセマフォではなく、匿名共有メモリを 'mmap'し、フォークする前にプロセス共有した' sem_init'を実行します。このようにして、名前を付けたリソースを取り除くことについて心配する必要はありません。 –

関連する問題