複数のfork()パイプを持つ子供

私はfork()で子を作成しているC ++でプログラムを作ろうとしています。 それはargvから子の番号を取って、これらの子を作成する必要があります、すべての子供は別のものを作成し、パイプでお互いに通信....

Example ./a.exe 2

**OUTPUT**
P1 exists
P2 created
Write message: Hello
P1 sending message (“Hello”) to P2
P2 received message (“Hello”) from P1

私はargvから番号を取得し、正しい数の子(私は思う)を作成し、パイプに読み書きするための関数は、すべてOKです。 しかし、私は複数の子供とそれを作ることが大変です!

  1. 私の最初の問題は、argvに2つ以上を置くと、子の順序
  2. しかし私の大きな問題は、もし私が     2単語のメッセージはスペースの前の最初の単語だけを読むことができます!!私はscanfを使用しています。

SOME OF MY CODE

//GETTING,CHECKING ARGV
//OPENING PIPE

         pid=fork();
         if (pid!=0){


                      waitpid(pid,&child_status,0);
                      printf("\n\n****Parent Process:ALL CHILD FINISHED!****");

                     }
          else if (pid==0)
          {

                 printf("\n P%d Exists \n",i); 
                     close (mypipe[READ_END]);
                      write(mypipe[WRITE_END], msg, 256);  /* write pipe*/                   
                       close (mypipe[WRITE_END]);          
                    printf("Write a message: \n");
                     scanf("%s",msg);
                       printf("\n P%d sending message: '%s' to P%d \n",i,msg,i+1); 

         do{
            childpid[i] = fork();
           if (childpid[i] > 0){   


                       /* wait for child to terminate */
                             waitpid(childpid[i],&child_status,0);  
                 }
           else if (childpid[i] == 0)
           {
               /*child process childpid = 0*/
               printf("\n P%d Created \n",i+1);
               close (mypipe[WRITE_END]);   
                 read(mypipe[READ_END], msg, 256);  /* read pipe */
                 close (mypipe[READ_END]);
                 printf("\n P%d received message: '%s' from P%d \n",i+1,msg,i);          
                 exit(0);
                 return;

            }
           else{
                   printf("Child Fork failed");
                   }
                      i++;
                   }

                   while (i

私は他の同様の質問を読んで、多くのことを試しましたが、助けにはなりませんでした! どんな助けもありがとう! ありがとうございました!

1
明らかに、それはすべてのコードではありません。 x がどのように宣言または設定されているかを示していません(おそらく argv [1] を整数に変換します)。 main()やヘッダーのような小さなものは見逃しています。
追加された 著者 Jonathan Leffler,
おそらく、いくつかのコードを表示する必要があります。私は、あなたが子供から印刷している順序外のメッセージについてあなたの苦情から疑うが、私は確かに言うことはできない。 scanfの問題は出力バッファリングの可能性が高いですが、ここでもあなたのコードが確実であることを確認する必要があります。
追加された 著者 Borealid,

1 答え

表示するコードに複数の問題があり、コメントに診断されたコードがありません。

1つ目の問題は、最初の子で唯一のパイプの両端を閉じてからもう一度閉じることです(ただし、幸いにもエラーは無視されます)。もっと真剣に、その後の子どもたちは仕事をするために閉鎖パイプしか持っておらず、それは彼らを助けるつもりはありません。

別の問題は、親プロセスがパイプを閉じないということです。このプログラムでは重要ではないかもしれません。なぜなら、あなたはEOFを読むことを試みていないからです。しかし、ほとんどのプログラムでは重要です。

別の問題は、パイプに初期化されていないメッセージを書き込もうとするまで、標準入力からメッセージを読み取らないことです。子の標準入力をパイプの読み込み側に接続する必要があるかどうかはすぐには分かりません。メッセージがそれほど長くなくても、パイプに256バイトを書き込む。

scanf( "%s"、msg)は最初の空白(空白、改行、タブなど)まで読み込むように設計されているため、複数の単語で問題が発生します。この文脈では、おそらく情報を読むために fgets()を使用します。

私は子供一人一人に新しいパイプが必要だと思います。おそらく、各システムコールをチェックする際にエラーが発生するはずですが、単純なエラー報告機能があれば簡単です。

#include 
#include 
#include 
#include 
#include 

static char *arg0 = 0;

static void err_exit(const char *fmt, ...)
{
    int errnum = errno;
    va_list args;
    va_start(args, fmt);
    fprintf(stderr, "%s (%d): ", arg0, (int)getpid());
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, "Error %d: %s\n", errnum, strerror(errnum));
    exit(1);
}

int main(int argc, char **argv)
{
    int i=1;
    int x;
    int pid, mypipe[2];
    pid_t childpid[256];
    int child_status;
    char msg[256];

    arg0 = argv[0];

    if (argc != 2 || (x = atoi(argv[1])) <= 0)
        err_exit("Usage: %s num-of-children\n", argv[0]);
    if (pipe(mypipe) < 0)
        err_exit("pipe error\n");

あるプロセスから次のプロセスにメッセージが中継されるように、どのように構成したいのかについて、真剣に考えています。これはほんの始まりに過ぎません...エラー報告機能はあなたの役に立つかもしれません。

1
追加された
本当にありがとうございました!:)私は以前fgets()を試していましたが、間違って使用していました。今、okです。そして、今私は正しいパイプをチェックしてデバッグメッセージを表示しています!私をunstackingのために非常にありがとう:)
追加された 著者 DarkPain,