2

私はcとプログラミングに非常に慣れていないので、助けが必要です。Linux(cygwin)のcでは、終了時にすべての子プロセスを削除する必要があります。私は他の同様の質問を見ましたが、それを機能させることができません。私はもう試した-

atexit(killzombies); //in parent process

void killzombies(void)
{
    printf("works");
    kill(0, SIGTERM);
    printf("works");
    if (waitpid(-1, SIGCHLD, WNOHANG) < 0)
         printf("works");
}

どういうわけか、「作品」は今までに印刷されません。ctrl+cを押して終了します。

また、私は試しました-

prctl(PR_SET_PDEATHSIG, SIGHUP); //in child process
signal(SIGHUP, killMe);

void killMe()
{
    printf("works");
    exit(1);
}

しかし、私はcygwinを使用しているので、私がcygwinを使用すると#include <sys/prctl.h>、ファイルまたはディレクトリが見つからないと言われ、インストールするパッケージがわかりません。また、私のprctl()機能が機能する場合、それはすべてのゾンビを殺しますか?

私のプログラムはクライアントサーバーであり、各クライアントを処理するためのサーバーforks()です。サーバーがシャットダウンしたときにゾンビを残さないと思います。

4

3 に答える 3

1

あなたwaitpidは通常のパラメータを提供していません、私はそれがクラッシュしないことに驚いています。プロトタイプは次のとおりです。

pid_t waitpid(pid_t pid, int *status, int options); 

2番目のパラメーターは、を指定するためのポインターであるint必要がありますintwaitpidまた、各子を呼び出す必要があることに注意してください。1人だけを呼び出しています。

atexit()正常に終了した場合にのみ呼び出されます。CTRL + Cで終了する場合は、SIGINTのハンドラーから関数を呼び出す必要があります。

于 2012-09-14T15:37:41.503 に答える
0

Linuxのドキュメントからatexit(3)

atexit()(および)を使用して登録された関数on_exit(3)は、シグナルの配信が原因でプロセスが異常終了した場合は呼び出されません。

アプリケーションがSIGINTまたはSIGTERMを受信したときにクリーンアップする場合は、適切なシグナルハンドラーをインストールし、そこで作業を行う必要があります。

于 2012-09-14T15:33:24.340 に答える
0

プロセスに含まれる子の数を追跡してから、その回数だけ待機を呼び出す必要があります。また、他の人が言っているように、プロセスがシグナルによって終了した場合、atexit()関数は呼び出されないため、シグナルハンドラーからもkillzombies()を呼び出す必要があります。次のようなものが必要になります。

int n_children = 0; // global

void handle_sig(int sig) {
    killzombies();
    exit(sig);
}

// your atexit()
void killzombies() {
    kill(0, SIGKILL);
    while (n_children > 0) {
        if (wait(NULL) != -1) {
            n_children--;
        }
    }
}
于 2012-09-14T16:09:11.443 に答える