2017-03-19 6 views
0

私はいくつかのCコードで遊んでいます。一連の子プロセスにいくつかの非同期作業をさせ、その後いくつかの同期作業を行わせようとしています。子どもの親を信号と同期させて一時停止する

親は、子供の同期性を整理することを担当しています。

#define CHILDREN 5 

void myHandle(int d) {} 

int main() { 
    int i; 
    int pid[CHILDREN]; 
    signal(SIGUSR1, myHandle); 
    for(i = 0 ; i < CHILDREN ; i++){ 
     pid[i] = fork(); 
     if (pid[i] == 0){ 

      // DO SOME ASYNCHRONOUS WORK 

      // tell my parent I am done: 
      kill(getppid(), SIGUSR1); 

      // wait for parent to wake me up. 
      pause(); 

      // DO SOME SYNCHRONOUS WORK 

      //wake parent back up. 
      kill(getppid() , SIGUSR1); 

      exit(1); 
     } 
    } 

    // Wait for all children to finish async work: 
    for (i = 0 ; i < CHILDREN ; i++) { 
     pause(); // ISSUE IS HERE 
    } 

    // wake children back up in order: 
    for (i = 0 ; i < CHILDREN ; i++) { 
     kill(pid[i], SIGUSR1); 
     // wait for child to finish work. 
     pause(); 
    } 

    return 0; 
} 

このコードは実際に動作する(ほとんどの時間):

は、ここでは、コードの一般的な考え方です。問題は、親がforループで一時停止していることです。いくつかのケースでは、複数の子どもが同時に非同期作業を終了するため、親に対して多くの殺害が呼び出されます。ループは、すべてのキルコールのために親が一時停止状態になるのに十分速く反復することができず、信号を受信しなかったポーズでプログラムが停止することになります。

ご意見やご指摘をお寄せいただければ幸いです。

答えて

1

可能な解決策は、主な機能にサイズがCHILDRENの配列を持つことです。子が終了したら、配列の要素に値を入れます。次に、父親は配列のすべてのフラグがアップしているかどうかを確認するだけです。ありがとうございました - 彼らそれぞれが自分のゾーンを持っているので

この方法では、

+0

ブリリアント、子供たちの間で紛争が記述されることはありません。 – Patrick

+0

唯一の問題は、父親がアクティブな待機状態にあることが必要であり、常にフラグが立っているかどうかをチェックすることです。あなたのソリューションでは、pause()はこれを受動的に待ちます。 – Pantoofle

+0

私はループでスリープして "あまりにも"ビジーではないようにします – Patrick

関連する問題