2017-04-05 7 views
0

私は子プロセスに3回信号を送る必要があります。ゾンビ状態を避けて何回か子供に信号を送るには? C言語

問題は、子供が信号を1回受信してからゾンビに変換することです。

予想される出力は次のようになります。

私は子供の11385だと私は私が子供の11385だと私は私が子供の11385と私だSIGUSR1

を受けSIGUSR1

を受けSIGUSR1

を受けた。しかし、実際の出力は、次のとおりです。

私は子供の11385だと私はSIGUSR1

01を受信
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

void my_handler() 
{ 
    printf("\n I'm the child %i and i received SIGUSR1\n", getpid()); 
} 


int main (int argc, char **argv) { 
    int *array; 
    int N = 10; 
    int i; 
    pid_t pid1; 
    array=(int*)malloc(sizeof(int)*N); 


    signal(SIGUSR1,my_handler); 

    for (i = 0; i< N; i++) 
    { 
     pid1 = fork(); 
     if(pid1 < 0) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid1 > 0) 
     { 
      array[i]= pid1; 
     } 

     else 
     { 
      sleep(100); 
      exit(EXIT_SUCCESS); 
     } 
    } 

    i=0; 
    while(i<3) // I need to call the son 3 times 
    { 
     kill(array[1], SIGUSR1); 
     i++; 
    } 
} 
+0

'無効my_handler()' - >> '無効my_handler(int型シグナム)' [間違った署名を使用すると、シグナルハンドラからの復帰が効果的にあなたの子供を殺す]そしてまた:あなたはシグナルハンドラの中からprintf()を呼び出すべきではありません。 – wildplasser

+0

@wildplasserコードは特定のシグナルの例であるため、引数はありません。 printfも例であり、実際の問題ではありません:/ –

+0

しかし、引数を指定して**呼び出されてスタックを破壊します(返品時) – wildplasser

答えて

1

子が信号を受信すると、おそらくsleepが終了するのを待っています。最初の信号は、時間が満了していなくてもsleepを中断し、errnoEINTRに設定された状態で復帰します。あなたが寝ていたい場合は、sleepに再度電話する必要があります。

+0

4回追加すると4回追加すると睡眠が追加され、2回表示されます。Nはどのように睡眠するのですか? とにかく、 SIGTERMシグナルが機能しない –

+0

スリープをループに入れるSIGTERMハンドラは、ループが終了することを示すグローバル変数を設定する必要があります(変数はvolatileでなければなりません) – rici

+0

またはsleepの戻り値をチェックします。理由はありますが、実際には、このユースケースの場合はかなりです。 –

1
  • あなたの親プロセスが
  • 信号は、高速に送信することができ、子供のためのINGの待ち時間()せずに終了し、私は私が信号のためのより多くの遅延に
  • 正しい署名を追加
  • 短い遅延を追加しましたハンドラはvoid handler(int signum)です。ハンドラが引数を指定して呼び出され、シグナルハンドラのスタックレイアウトが異なるため、これは非常に重要です。
  • シグナルハンドラからprintf()を呼び出すべきではありません。非同期では安全ではありません。

#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

char pidstr[10]; 
char massage[]="  I'm the child and i received SIGUSR1\n"; 

#define CNT 1 
void my_handler(int signum) 
{ 
write(0, massage, strlen(massage)); 
} 


int main (int argc, char **argv) { 
    int i , err, status; 
    pid_t pid1; 
    int array[CNT]; 

    signal(SIGUSR1, my_handler); 

    for (i = 0; i< CNT; i++) { 
     pid1 = fork(); 
     if(pid1 < 0) { exit(EXIT_FAILURE); } 
     else if (pid1 > 0) { 
       printf("ChildPid=%d\n", pid1); 
      array[i]= pid1; 
     } 

     else 
     { // child 
       // signal(SIGUSR1, my_handler); 
      sprintf(pidstr,"[%d]", getpid()); 
      memcpy (massage,pidstr, strlen(pidstr)); 
      sleep(10); 
       printf("Unslept\n"); 
      sleep(10); 
       printf("Unslept\n"); 
      sleep(10); 
       printf("Unslept\n"); 
      exit(EXIT_SUCCESS); 
     } 
    } 
    sleep(10); 
    for (i=0; i<3; i++) { 
     err = kill(array[0], SIGUSR1); 
     printf("Err=%d:%d\n", err, (err) ? errno: 0); 
     sleep(1); 
    } 

    while ((pid1=wait(&status)) != -1){ 
     printf("[Parent] Reaped %d\n", pid1); 
     } 

return 0; 
} 
関連する問題