1

「ps」を実行し、それを「grep」、基本的に「ps |」にパイプする単純なCプログラムがあります。grep x'.

コードは多かれ少なかれ次のようになります。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(){
    int pipefd[2];
    int pid;

    pipe(pipefd);
    pid=fork();

    if (pid == 0){
        close(pipefd[1]);
        dup2(pipefd[0], 0);
        close(pipefd[0]);
        execlp("grep", "grep", "b", (char *) 0);
    }
    else{
        close(pipefd[0]);
        dup2(pipefd[1], 1);
        close(pipefd[1]);
        execlp("ps", "ps", (char *) 0);
    }
    exit(0);
}

私が抱えている問題は、これを unix (Solaris) で実行すると完璧に動作しますが、(Debian) で実行すると正しく実行されますが、エラー メッセージが表示されることです。

エラーメッセージ:

Signal 17 (CHLD) caught by ps (procps-ng version 3.3.3).
ps:display.c:59: please report this bug

「ls」や「grep」などの異なるコマンドを実行する同じプログラムを試しましたが、どちらの OS でも問題はありませんでした。「ps」の違いは何ですか?

編集:
含まれているライブラリをコードに追加しました。

4

1 に答える 1

2

プログラムが fork を呼び出すと、親プロセスと子プロセスが作成されます。子プロセスでは fork は 0 を返し、親プロセスでは 1 を返します。子プロセスが終了するたびに、SIGCHLD シグナルが親プロセスに送信されます。

ここで、あなたの場合execlp、親プロセスと子プロセスの両方を呼び出します。これにより、実行中のプロセス イメージが置き換えられますが、関係は変更されません。これは、それpsが親プロセスでgrepあり、子プロセスであることを意味します。通常、プログラムはデフォルトで SIGCHLD を無視しますが、ps未知のシグナルをすべてキャッチし、そこに表示されるメッセージで終了するため、これは問題になりません。関連する関数は、(または) のソース コードpsprocpsで確認できます。

于 2013-05-29T04:31:14.820 に答える