2

それぞれに 2 つのハンドラー (SIGTSTP、SIGCHLD) があります。SIGTSTP を使用してプロセスを一時停止すると、SIGCHLD のハンドラー関数も実行されます。これを防ぐにはどうすればよいですか。

シグナルハンドラ:

void signalHandler(int signal) {
int pid, cstatus;
if (signal == SIGCHLD) {
    susp = 0;
    pid = waitpid(-1, &cstatus, WNOHANG);
    printf("[[child %d terminated]]\n", pid);
    DelPID(&JobsList, pid);
}
}

void ctrlZsignal(int signal){
    kill(Susp_Bg_Pid, SIGTSTP);
    susp = 0;
    printf("\nchild %d suspended\n", Susp_Bg_Pid);
}

Susp_Bg_Pid は、一時停止されたプロセス ID を保存するために使用されます。
susp は、親プロセスが中断されているかどうかにかかわらず、親プロセスを「スマッシュ」する状態を示します。

4

1 に答える 1

4

sigactionwithを使用して SIGCHLD ハンドラを設定しますSA_NOCLDSTOP

sigaction より (2)

SA_NOCLDSTOP - signum が SIGCHLD の場合、子プロセスが停止したとき (つまり、SIGSTOP、SIGTSTP、SIGTTIN、または SIGTTOU のいずれかを受け取ったとき) または再開したとき (つまり、SIGCONT を受け取ったとき) に通知を受け取りません (wait(2) を参照)。このフラグは、SIGCHLD のハンドラーを確立する場合にのみ意味があります。

アップデート

void signalHandler(int sig)
{
  //...
}

struct sigaction act;

act.sa_handler = signalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP;

if (sigaction(SIGCHLD, &act, 0) == -1)
{
  perror("sigaction");
  exit(1);
}

使い慣れていない場合はsigaction、非常に優れたいくつかの異なるオプションと動作があるためsignal、使用方法を理解する前に複雑さと混乱を招くため、よく読んでください。私はあなたがやりたいと思われる最低限のことを推測しましたが、遅かれ早かれこれを学ぶ必要があります.

于 2013-11-09T23:07:03.170 に答える