2

所以我写了一个程序,使用管道和 execl 来做一些算术。我不确定如何调试管道和不同的进程,但据我所知,这与我的管道读取数字有关。所以到目前为止我的设置是创建孩子,并根据他们给定的操作,他们执行到不同的程序,这些程序将计算管道中的写入值。我不知道我是否应该在父级将其值写入子级之后在读取结果之前在父级中实现等待或其他操作。我不断得到 Z 作为我的输出。

所以这是我要执行的文件之一,其他文件看起来完全相同,只是显示了相应的操作:

#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

让我们简化这段代码。没有操作 - 仍然不起作用。只有一个孩子——还是不行。只有一根管子——还是不行。没有文件 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 回答