SIGCHLDとwaitpid()またはwait()の関係は何ですか?

SIGCHLDとwaitpid()またはwait()の関係は何ですか?

私が正しい場合、プロセスは関数を呼び出して子プロセスが終了または停止するのを待ちますwaitpid()wait()

waitpid()SIGCHLD信号とor関数の関係は何ですかwait()

  • プロセスwaitpid()がまたはwait()関数を呼び出すときに子プロセスがシャットダウン/停止されるまで(SIGCHLD信号を送信する前と同じ)、プロセスはそれ自体が停止することは正しいですか?

    (シグナルが送信されるまで現在のプロセスを中断します。SIGCHLDが送信されるまでを除いて同様であるかどうか疑問にpause()思います。)waitpid()

  • SIGCHLDが呼び出しによって中断されたプロセスに送信されるとき、waitpid()SIGCHLDハンドラの実行と中断から再開の間の順序は何ですかwaitpid()
    (次のコンピュータシステムの例では:プログラマの観点からSIGCHLDハンドラを呼び出しますwaitpid()。)

ありがとうございます。

void handler(int sig)
{
  int olderrno = errno;

  while (waitpid(-1, NULL, 0) > 0) {
    Sio_puts("Handler reaped child\n");
  }
  if (errno != ECHILD)
    Sio_error("waitpid error");
  Sleep(1);
  errno = olderrno;
}

int main()
{
  int i, n;
  char buf[MAXBUF];

  if (signal(SIGCHLD, handler1) == SIG_ERR)
    unix_error("signal error");

  /* Parent creates children */
  for (i = 0; i < 3; i++) {
    if (Fork() == 0) {
      printf("Hello from child %d\n", (int)getpid());
      exit(0);
    }
  }

  /* Parent waits for terminal input and then processes it */
  if ((n = read(STDIN_FILENO, buf, sizeof(buf))) < 0)
    unix_error("read");

  printf("Parent processing input\n");
  while (1)
    ;

  exit(0);
}

ベストアンサー1

wait()は1970年代の無駄なUNIXシステムコールであり、waitpid()1980年代の無駄なUNIXシステムコールです。

waitid()1988年には高度なインターフェースが導入されました。

signal()また、1970年代の古いインターフェースでもあります。最も近いインターフェイスが呼び出され、sigaction()信号の動作を制御できます。あなたの場合、一般的な通貨は次のとおりです。

    struct sigaction sa; 

    sa.sa_sigaction = handler; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = SA_RESTART|SA_SIGINFO; 

    sigaction(SIGCHLD, &sa, NULL); 

に追加すると、SA_NOCLDWAITまったくsa.sa_flags呼び出す必要はなく、wait*()システムはwait*()呼び出されるまでゾンビプロセスを維持しません。

追加すると、SA_NOCLDSTOPcildプロセスが終了したときにSIGCHLDハンドラは呼び出されません。

SIGCHLDaが生成されると、関数が呼び出されます。

void handler(int sig, siginfo_t *sip, void *context)

子プロセスが死んだとき。このパラメータはsigシグナル番号で埋められ、2番目のパラメータは以下のように呼び出しSIGCHLDで得られたのと同じ情報で埋められます。waitid()

struct siginfo si;

ret = waitid(P_PID, pid, &si, WEXITED|WSTOPPED|WTRAPPED);

したがって、子プロセスの状態に興味がない場合はシステムに通知することができ、子プロセスを呼び出すことには興味がありませんが、wait*()まだプロセスの状態を取得したい場合は、システムに通知して情報を使用できます。シグナルハンドラ関数の2番目のパラメータにあります。

子プロセスが終了してstruct siginfo確認されると、次のフィールドが入力されます。

si.si_signo   /* The signal number SIGCHLD */
si.si_code    /* The reason for the child to exit */
si.si_status  /* Either the parameter to exit(r) or signal number */
si.si_pid     /* The process id of the child that died */

si.si_code値が含まれるCLD_EXITEDと、完全なsi.si_status32ビットコードが含まれます(POSIXシステムの場合)exit()

、またはが含まれているsi.si_code場合は、状態変更を引き起こした信号番号が含まれます。CLD_KILLEDCLD_DUMPEDCLD_TRAPPEDCLD_STOPPEDCLD_CONTINUEDsi.si_status

おすすめ記事