4

私はこの質問で可能なすべての出力を見つけるように求められます:

#define N 4
int val = 9;
void handler(sig) {
   val += 3;
   return;
}
int main() {
  pid_t pid;
  int i;
  signal(SIGCHLD,handler);
  for (i=0;i<N;i++) {
    if ((pid =fork()) == 0) {
        val -= 3;
        exit(0);
    }
  }
  for (i=0;i<N;i++) {
    waitpid(-1,NULL,0);
  }
  printf("val = %d\n",val);
}

ラインシグナル(SIGCHLD、ハンドラー)が何をするのかわかりません。私は次のものだけを見つけました:

SIGABRT - abnormal termination.
SIGFPE - floating point exception.
SIGILL - invalid instruction.
SIGINT - interactive attention request sent to the program.
SIGSEGV - invalid memory access.
SIGTERM - termination request sent to the program.

SIGCHLDは何をしますか?この質問のforループについても説明できますか?

このコードをコンパイルして実行するには、どのようなライブラリが必要ですか?

4

3 に答える 3

5

親プロセスから子プロセスを fork すると、SIGCHLD が設定されますが、ハンドラ関数は実行されません。子プロセスが終了すると、SIGCHLD がトリップし、ハンドラー関数内のコードが実行されます...

于 2013-10-20T02:31:22.283 に答える
3

奇妙なプログラム。

私があなたに見せようとしていると思うのは、SIGCHLDが引き起こすものと、子によって変更された子プロセスの変数が親に影響を与えない方法です。

fork() すると、子プロセスが作成されます。おなじみですか?親プロセス ( fork() を呼び出したプロセス) がシグナルを受信します。ハンドラが実行されます。プログラムを実行すると、21 のうちの数が表示されるはずです。

これは、シグナルハンドラが実行されるたびに val が 3 ずつインクリメントされるためです。 9 + ( 3*4)=21 です。このコードは 4 つの子を作成します。

子プロセス

値 -= 3; 終了 (0);

値を減少させます。しかし、これは元の子プロセスではなく別のプロセスで発生するため、独自のローカル コピーがあるため、「元の」val 変数には影響しません。

于 2012-12-10T02:10:26.663 に答える
0

@jim mcnamaraの回答には、可能なすべての出力がリストされていないと思います。

複数の信号が 1 つに折りたたまれる可能性があるため、1 <= k <= 4 の場合は 9+(3*k) が可能です。

于 2019-10-10T12:10:07.147 に答える