0

UNIX パイプがユーザー入力を正しく要求するようにしようとしています。1 つのパイプを使用して 3 つの子プロセスを作成する必要があります。各子プロセスは、ユーザーに整数を入力するように求め、それをパイプに書き込みます。親プロセスは、3 つの整数すべてと、それぞれをパイプに書き込んだプロセスのプロセス ID を表示します。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char argv[]) {
    int input = 0;
    int pd[2];
    int i =0;
    int buffer[100];
    int output = 0;

    if (pipe(pd) == - 1) {
        fprintf(stderr, "Pipe Failed");
    }

    for (i=0; i<3; i++) {
        if (fork() == 0) { // child process
            printf("\nMy process id is: %d", getpid());
            printf("\nEnter an integer: ");  
            scanf("%d", &input);
            if (write(pd[1], &input, sizeof(int)) == -1) {
                fprintf(stderr, "Write Failed");
            }
            return (0); // Return to parent. I am not really sure where this should go 
        } // end if statement
    } // I am not quite sure where the for loop ends

    // Parent process
    close(pd[1]); // closing the write end

    for (i = 0; i < 3; i++) {
        if (read(pd[0], &output, sizeof(int) )== -1) {
            fprintf(stderr, "Read failed"); 
        }
        else {
            buffer[i] = output;
            printf("Process ID is: %d\n", pid);
        }
    } 
    printf("The numbers are %d, %d, %d", buffer[0], buffer[1], buffer[2]);
    return(0);
}

編集後、出力として得られるようになりました:

My process id is: 2897
Enter an integer: My process id is: 2896
Enter an integer: 
My process id is: 2898
Enter an integer: 4
Process ID is: 2898
78
Process ID is: 2898
65
Process ID is: 2898
The numbers are 4, 78, 65

これははるかに近いですが、親が子プロセスを待つようにする方法はまだわかりません。各番号をプロセス ID とともに出力しようとすると、最新のプロセス ID のみが出力されます。

すべての printf ステートメントは scanf ステートメントの前に実行されるため、プロンプトが 3 回表示されるまで何も入力できません。

4

2 に答える 2

0
if (read(pd[0]), &output, sizeof(int) )== -1)
              ^ // this is wrong

あなたの括弧は間違っていますが、それはタイプミスだと思います。

また、読み取りが失敗した場合にのみバッファを更新します...次のようにする必要があります。

if (read(pd[0], &output, sizeof(int) )== -1) {
    fprintf(stderr, "Read failed");
}
else {
    buffer[i] = output;
}

ただし、このコードを改善する方法はたくさんあります。他の回答を見て、(-Wall with gcc) で警告を表示してプログラムをコンパイルします。

于 2013-05-21T00:15:29.557 に答える
0

任意の時点でユーザーと対話できるプロセスは 1 つだけです。子 1 が完了するまで子 2 が何もしないように調整する必要があります。これを行う最も簡単な方法はwait()、次の子をフォークする前に、各子の親を連続して持つことです。 編集:それは次のようになります:

for (i = 0; i < 3; i++) {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // your existing child code goes here
    } else {
        // parent:
        int status;
        if (waitpid(pid, &status, 0) != pid) {
            perror("wait");
            return 1;
        } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
            fprintf(stderr, "child %d unexpected exit %d\n", i, status);
            return 1;
        }
    }
}

PIPE_BUFパイプに書き込まれるデータの量は非常に短いため (合計バイト未満でPIPE_BUFあり、少なくとも 512 であることが保証されています)、すべての子プロセスが終了するまで、パイプからの読み取りを安全に遅らせることができます。これは、子供たちがより長いメッセージを送り返す場合には当てはまりません。

main整数を返します。return;最初のループ内のステートメントは必要であり、最後 ( final の後) にreturn 0;別のステートメントが必要です。return 0;printf

最初のループは、ネストされたステートメントforの後など、終了する必要がある場所で終了します。その周りに別の中括弧のセットを配置ifすることができfor (...)ます - の直後に中括弧を開き、コメントがある場所で右中括弧を閉じます// I am not quite sure- 多くの人がその方が良いスタイルだと考えるでしょうが、そうする必要はありません.

于 2013-05-21T00:09:18.737 に答える