この C コードの何が問題になっていますか? 子供が帰ってこない?

user3499524

ここでは、2 つの子プロセス間で正しいパイピングを行う方法を理解しようとしています。ある Linux コマンドの出力を別のコマンド (ls から cat へ) に渡して、プログラムを正常に戻そうとしているだけです。ただし、フォークされた2番目の子は動けなくなり、親はこの子を永遠に待っていると推測しています。私は長い間、このコードをいじって、なぜ動かなくなったのかを突き止めようとしてきました。私は C システム プログラミングに関しては初心者ですが、勉強しようとしています。

プログラムが終了せず、猫にハングアップする理由を知っている人はいますか?

どんな助けでも大歓迎です。

ありがとう。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
    char *a[2] = {"/bin/ls", NULL};
    char *b[2] = {"/bin/cat", NULL};
    char *envp[2] = {getenv("PATH"), NULL};
    int fd[2], status;
    pipe(fd);
    int old_std_out = dup(1);
    int old_std_in = dup(0);
    dup2(fd[1], 1);
    int pid = fork();
    switch(pid)
    {
        case -1:
            perror("Forkscrew");
            exit(1);
            break;
        case 0:
            execve(a[0], a, envp);
            exit(0);
            break;
       default:
            waitpid(-1, &status, 0);
            dup2(old_std_out, 1);
            break;
    }
    dup2(fd[0], 0);
    pid = fork();
    switch(pid)
    {
        case -1:
            perror("Forkscrew");
            exit(1);
            break;
        case 0:
            execve(b[0], b, envp);
            exit(0);
            break;
        default:
            waitpid(-1, &status, 0);
            dup2(old_std_in, 0);
            break;
    }
    printf("\n");
    return 0;
}
EOF

プログラムには 2 つの潜在的なデッドロックがあります。

まず、最初の子 ( ls) はパイプに書き込もうとしてブロックする可能性があります。その場合終了するまでwaitpid()戻らず、2 番目の子 ( ) が実行を開始するまで終了しませんこれは、戻るまで発生しません=> デッドロック。lslscatwaitpid()

第二に、書き込み終了のすべてのファイル記述子が閉じられるまで、catそこから読み取りstdinます。親プロセスcat書き込み終了のコピーの両方が、明示的に知らなくcatてもそれ持っています。一部のオペレーティング システムではread()、書き込みエンドの唯一のコピーが同じプロセス内にある場合 (このデッドロックを回避するため) はブロックされませんが、これは保証されません。いずれにせよ、親プロセスはファイル記述waitpid()子のコピーを保持し、親プロセスはパイプの書き込み終了を待つ子プロセスを保持するため、再びデッドロックが発生します。

多くの場合、プログラムを単純化すると、次のような問題が解決します。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
    char *a[2] = {"/bin/ls", NULL};
    char *b[2] = {"/bin/cat", NULL};
    char *envp[2] = {getenv("PATH"), NULL};
    int fd[2], status;
    pipe(fd);
    //int old_std_out = dup(1); /*No need to copy stdout...*/
    //int old_std_in = dup(0);  /*...or stdin...*/
    //dup2(fd[1], 1);           /*...if you wait dup2()ing until you need to*/
    int pid = fork();
    switch(pid)
    {
        case -1:
            perror("Forkscrew");
            exit(1);
            //break; /*unreachable*/
        case 0:
            dup2(fd[1], STDOUT_FILENO); /*NOW we dup2()*/
            close(fd[0]); /*no need to pass these file descriptors to...*/
            close(fd[1]); /*...a program that doesn't expect to have them open*/ 
            execve(a[0], a, envp);
            exit(0); /*might want an error message*/
            //break; /*unreachable*/
       default:
            //waitpid(-1, &status, 0); /*don't wait yet*/
            //dup2(old_std_out, 1);
            close(fd[1]); /*we don't need this in the parent anymore*/
            break;
    }
    //dup2(fd[0], 0); /*not needed anymore*/
    pid = fork();
    switch(pid)
    {
        case -1:
            perror("Forkscrew");
            /*might want to ensure the first child can terminate*/
            exit(1);
            //break; /*unreachable*/
        case 0:
            dup2(fd[0], STDIN_FILENO);
            close(fd[0]); /*again, cat doesn't expect a fourth fd open*/
            execve(b[0], b, envp);
            /*again, error message would be nice*/
            exit(0);
            //break;
        default:
            //waitpid(-1, &status, 0);
            //dup2(old_std_in, 0);
            break;
    }
    waitpid(-1, &status, 0); /*don't wait until both children are created*/
    waitpid(-1, &status, 0);
    printf("\n");
    return 0;
}

ご覧のとおり、改善のための多くの提案を残しましたが、execve()s が正常に機能していれば、これで既に正常に動作するはずです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

このC ++のコードの何が問題になっていますか?

分類Dev

このCコードの何が問題になっていますか?

分類Dev

このコードの何が問題になっていますか?Objective C

分類Dev

C ++コード:これの何が問題になっていますか?

分類Dev

このC ++コードの何が問題になっていますか?(コンソール)

分類Dev

この単純なコード(Objective c)の何が問題になっていますか?

分類Dev

C ++でのこのファイル処理コードの何が問題になっていますか?

分類Dev

C ++でのこのファイル処理コードの何が問題になっていますか?

分類Dev

HCFを見つけるためのこのCコードの何が問題になっていますか?

分類Dev

このcコード(リンクリストの実装)の何が問題になっていますか?

分類Dev

cの私のコードの何が問題になっていますか

分類Dev

多項式のcコードを追加することの何が問題になっていますか?

分類Dev

破壊を使用するこのc ++コードの何が問題になっていますか?

分類Dev

私のC#コードの何が問題になっていますか

分類Dev

私のCコードの何が問題になっていますか?

分類Dev

C ++のコードの何が問題になっていますか?

分類Dev

私のコードの何が問題になっていますか? c ++

分類Dev

このc ++リンクリストコードの何が問題になっていますか?

分類Dev

C#コードの何が問題になっていますか?

分類Dev

ここでのアルゴリズムで何が起こっているのか、コードはCの再帰問題に関連していますか?

分類Dev

C#のこの数式の何が問題になっていますか?

分類Dev

私のこのC ++再帰関数の何が問題になっていますか?

分類Dev

cは初めてですが、コードの何が問題になっていますか

分類Dev

Cでのこのヒープソートの実装の何が問題になっていますか?

分類Dev

次のcコードの何が問題になっていますか?MISRA品質警告メッセージ

分類Dev

私のC#アップデートコードの何が問題になっていますか?

分類Dev

C ++マージソートコードの何が問題になっていますか?

分類Dev

このコードのmetricsargの何が問題になっていますか?

分類Dev

このコードのchrの何が問題になっていますか?

Related 関連記事

  1. 1

    このC ++のコードの何が問題になっていますか?

  2. 2

    このCコードの何が問題になっていますか?

  3. 3

    このコードの何が問題になっていますか?Objective C

  4. 4

    C ++コード:これの何が問題になっていますか?

  5. 5

    このC ++コードの何が問題になっていますか?(コンソール)

  6. 6

    この単純なコード(Objective c)の何が問題になっていますか?

  7. 7

    C ++でのこのファイル処理コードの何が問題になっていますか?

  8. 8

    C ++でのこのファイル処理コードの何が問題になっていますか?

  9. 9

    HCFを見つけるためのこのCコードの何が問題になっていますか?

  10. 10

    このcコード(リンクリストの実装)の何が問題になっていますか?

  11. 11

    cの私のコードの何が問題になっていますか

  12. 12

    多項式のcコードを追加することの何が問題になっていますか?

  13. 13

    破壊を使用するこのc ++コードの何が問題になっていますか?

  14. 14

    私のC#コードの何が問題になっていますか

  15. 15

    私のCコードの何が問題になっていますか?

  16. 16

    C ++のコードの何が問題になっていますか?

  17. 17

    私のコードの何が問題になっていますか? c ++

  18. 18

    このc ++リンクリストコードの何が問題になっていますか?

  19. 19

    C#コードの何が問題になっていますか?

  20. 20

    ここでのアルゴリズムで何が起こっているのか、コードはCの再帰問題に関連していますか?

  21. 21

    C#のこの数式の何が問題になっていますか?

  22. 22

    私のこのC ++再帰関数の何が問題になっていますか?

  23. 23

    cは初めてですが、コードの何が問題になっていますか

  24. 24

    Cでのこのヒープソートの実装の何が問題になっていますか?

  25. 25

    次のcコードの何が問題になっていますか?MISRA品質警告メッセージ

  26. 26

    私のC#アップデートコードの何が問題になっていますか?

  27. 27

    C ++マージソートコードの何が問題になっていますか?

  28. 28

    このコードのmetricsargの何が問題になっていますか?

  29. 29

    このコードのchrの何が問題になっていますか?

ホットタグ

アーカイブ