簡體   English   中英

如何正確地從管道接收數據?

[英]How to correctly receive data from pipes?

因此,我使用管道和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

讓我們簡化這段代碼。 沒有操作-仍然行不通。 只有一個孩子-仍然沒有工作。 只有一根管道-仍然不起作用。 沒有文件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個管道。 分別測試操作項 ,然后將其拼接。

我相信這證明了簡化代碼的能力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM