2

そこで、パイプと execl を使用して演算を行うプログラムを作成しました。パイプやさまざまなプロセスをデバッグする方法はわかりませんが、私が見ることができるのは、数値を読み取るパイプと関係があるはずです。したがって、これまでの私のセットアップでは、子が作成され、指定された操作に基づいて、パイプに書き込まれた値を計算するさまざまなプログラムに実行されます。結果を読み取る前に、値を子に書き込んだ後、親に待機または何かを実装する必要があるかどうかはわかりません。出力としてZを取得し続けます。

したがって、これは私が実行しているファイルの1つであり、他のファイルはまったく同じように見え、対応する操作を示しているだけです:

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>

using namespace std;

main(int argc, char *argv[])
{
    int x, y, z;
    while (read(0, (char *)&x, sizeof(int)) &&
           read(3, (char *)&y, sizeof(int))) {
        z = x * y;
        if (argc > 1)
            cerr << "multiply: " << x << " * " << y << " = " << z << endl;
        write(1, (char *)&z, sizeof(int));
    }
}

これは私のコードで、実際に計算を行っていて、パイプが正しく設定されていると思います。時間を節約するために、パイプのセットアップについて少し説明します。子 0 -- パイプ 0 1 から読み取り、2 に書き込みます。子 1 はパイプ 2 と 3 から読み取り、4 に書き込みます。親は 0 1 3 に書き込み、4 から読み取ります。私のコード:

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;

const int MAX =21;
int pipes[MAX][2];
char operations[MAX];

int main()
{
    int a=0;
    int n;
    fstream datafile;
    pid_t pid;
    string line;
    datafile.open("data1.txt");
   

   if(datafile)
    {

        string input;
        getline(datafile, input);
        
        for(int i=0; i< input.size(); i++)
        {

    
            if (input[i] == '*'|| input[i] == '/'||input[i] == '+'||input[i] == '-')
            {
      
                operations[a] = input[i];
                a++;

            }

        }
      n = (a);

        for(int i =0; i<(2*n+1); i++)
           pipe(pipes[i]);

        for (int i=0; i <n; i++)
        {    
           pid = fork();
            if(pid == 0)
            {
             
                close(0);
                dup(pipes[2*i][0]);
                close(3);
                dup(pipes[2*i+1][0]);
                close(1);
                dup(pipes[2*i+2][1]);
              
            
                    switch(operations[i])
                    {
                    case '+':
                        execl("add","add", NULL);
                    case '-': 
                        execl("subtract","multiply", NULL);
                    case '*':
                        execl("multiply","multiply", NULL);
                    case '/':
                        execl("divide","divide", NULL);
                    
                    }

                 cout<< "No match for operation!";
            }
            else if(pid <0)
            cerr<<"Fork has failed";
          }
    
        int x, y, z;

        for(int i=0; i<3; i++)
          {
            getline(datafile,line);
            istringstream ins(line);
            ins >> x >> y >> z;

            write(0,(char *)&x, sizeof(x));
            write(3,(char *)&z, sizeof(z));
            write(1,(char *)&y, sizeof(y));
          }
          
          close(0);
          close(3);
          close(1);
        }  
        
            else
                cerr<<"Error reading file";
          


          datafile.close();
          
            int result;
            while(read(pipes[2*n][1],(char *)&result,sizeof(result)))
                cout<<result<<endl;
    
        
        
 
        



}

データファイルは次のようになります。

a * b * c

30 40 50

100 3 6

4

1 に答える 1

1

このコードを単純化しましょう。操作はありません -- まだ動作しません。子供は 1 人だけで、まだ機能していません。パイプは 1 つだけです -- まだ機能しません。ファイル I/O がありません -- まだ動作しません。親から子に 30 という数字を渡そうとしています:

  int pipes[1][2];

  pid_t pid;

  pipe(pipes[0]);

  pid = fork();
  if(pid == 0)
    {
      cout << "child here" << endl;
      close(0);
    }
  else if(pid <0)
    cerr<<"Fork has failed";

  cout << "parent here " << endl;

  int x = 30;
  write(0,(char *)&x, sizeof(x));
  close(0);

  int result;
  read(pipes[0][1],(char *)&result,sizeof(result));
  cout << "result is " << result << endl;

バグが見えますか?さらに一歩進んで、パイプ通信を完全に削除しましょう。

pid_t pid;
pid = fork();
if(pid == 0)
  {
    cout << "child here" << endl;
  }
else if(pid <0)
  cerr<<"Fork has failed";

cout << "parent here " << endl;

バグが見えますか?私たちはそれを修正します:

pid_t pid;
pid = fork();
if(pid == 0)
  {
    cout << "child here" << endl;
    return(0);
  }
else if(pid <0)
  cerr<<"Fork has failed";

cout << "parent here " << endl;

そして、パイプを元に戻します:

  int pipes[1][2];

  pid_t pid;

  pipe(pipes[0]);

  pid = fork();
  if(pid == 0)
    {
      cout << "child here" << endl;

      close(0);

      int result;
      read(pipes[0][1],(char *)&result,sizeof(result));
      cout << "result is " << result << endl;
      return(0);
    }
  else if(pid <0)
    cerr<<"Fork has failed";

  cout << "parent here " << endl;

  int x = 30;
  write(0,(char *)&x, sizeof(x));
  close(0);

バグが見えますか?パイプのバグを修正してから、最大 2 つの子と 5 つのパイプに戻します。操作を個別にテストしてから、スプライスします。

これは、コードを簡素化する力を示していると思います。

于 2013-08-14T16:07:03.207 に答える