私が正しい場合、プロセスは関数を呼び出して子プロセスが終了または停止するのを待ちます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_NOCLDSTOP
cildプロセスが終了したときにSIGCHLDハンドラは呼び出されません。
SIGCHLD
aが生成されると、関数が呼び出されます。
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_status
32ビットコードが含まれます(POSIXシステムの場合)exit()
。
、またはが含まれているsi.si_code
場合は、状態変更を引き起こした信号番号が含まれます。CLD_KILLED
CLD_DUMPED
CLD_TRAPPED
CLD_STOPPED
CLD_CONTINUED
si.si_status