在 C++ 中创建多个进程并与管道通信

Posted

技术标签:

【中文标题】在 C++ 中创建多个进程并与管道通信【英文标题】:Creating Multiple Processes and Communicating with Pipes in C++ 【发布时间】:2020-11-12 23:40:20 【问题描述】:

我正在尝试创建两个具有共享父进程的子进程,父进程必须打印每个子进程的输出,它向子 A 发送一个数字列表,子 A 对这些数字进行排序,然后发送排序后的list 给父母和孩子 B,然后孩子 B 找到数字列表的中位数,并将其发送给父母,在那里打印两个结果。

我遇到的问题是它对子 A 执行良好并打印子 A 的结果,但不为子 b 打印任何内容。

#include <string>
#include <vector>
#include <cstdlib>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char **argv)

    vector<int> numbers;
    vector<int> sortedVector;
    if (argc == 6)
    
            //Create vector
            numbers.push_back(atoi(argv[1]));
            numbers.push_back(atoi(argv[2]));
            numbers.push_back(atoi(argv[3]));
            numbers.push_back(atoi(argv[4]));
            numbers.push_back(atoi(argv[5]));
    
    else
    
        cout << "Error\n";
    
    int fd[2];
    int fd1[2];

    if (pipe(fd) == -1 || pipe(fd1) == -1)
    
        std::cout << "Pipe failed.\n";
    
    int child_a, child_b;
    child_a = fork();

    //Child A process
    if (child_a == 0)
    
        //Child A code
        sortedVector = numbers;
        sort(sortedVector.begin(), sortedVector.end());
        int array1[5] =  sortedVector.at(0), sortedVector.at(1), sortedVector.at(2), sortedVector.at(3), sortedVector.at(4) ;
        
        //Send to parent
        close(fd[0]);
        write(fd[1], array1, 5*sizeof(int));
        close(fd[1]);

        //Send to B
        close(fd1[0]);
        write(fd1[1], array1, 5*sizeof(int));
        close(fd1[1]);
    
    else
    
        child_b = fork();

        if (child_b == 0)
        

            //Child B code
            cout << "Array from A ";
            //Read from A
            int arrayFromA[5] =  0, 0, 0, 0, 0 ;
            close(fd1[1]);
            read(fd1[0], arrayFromA, 5*sizeof(int));
            close(fd1[0]);
            
            //Find median
            double median; 
            int arraySize = sizeof(arrayFromA) / sizeof(arrayFromA[0]);

            median = (double)(arrayFromA[(arraySize - 1) / 2] + arrayFromA[arraySize / 2]) / 2.0;

            //Send to Parent
            close(fd1[0]);
            write(fd1[1], &median, sizeof(double));
            close(fd1[1]);
        
        else
        
            //Parent code
            //Read from Child A
            vector<int> vectorFromChild;
            close(fd[1]);
            int array2[5] =  0, 0, 0, 0, 0 ;
            read(fd[0], array2, 5*sizeof(int));
            close(fd[0]);

            std::cout << "The sorted list: ";
            for (int i = 0; i < 5; i++)
               
                if (i != 4)
                
                    std::cout <<  array2[i] << ", ";
                
                else
                
                    std::cout << array2[i] << ".";
                
                    
            
            std::cout << std::endl;

            //Read from Child B
            double medianOutput;
            close(fd1[1]);
            read(fd1[0], &medianOutput, sizeof(double));
            close(fd1[0]);

            std::cout << "The median of the list is: " << medianOutput << std::endl;
            wait(NULL);
           
    

它甚至不会打印:“列表的中位数是:”

【问题讨论】:

【参考方案1】:

在 Child B 代码中,您在第 68 行 close(fd[1]),然后在第 80 行写入:write(fd1[1], &amp;median, sizeof(double));

UNIX 给我们返回值是有原因的。

【讨论】:

注意到,但奇怪的是,如果我使用 gdb 运行,它会正确输出,但不是正常输出,即使在此更改之后... 如果您将cout &lt;&lt; "Array from A "; 行注释掉,它会起作用吗? C++ 对我来说是个谜,主要是通过逐次逼近来编程。 不是 C++,如果你在 cout 所在的地方放一个 sleep(1) ,你会发现问题; main 将在 B 之前从 fd1 读取。您要么需要 B 写入并从 fd[] 进行主要读取,要么设计一种方法来同步两者。

以上是关于在 C++ 中创建多个进程并与管道通信的主要内容,如果未能解决你的问题,请参考以下文章

subprocess库:Python中创建附加进程

Linux进程间通信

实验八进程间通信

实验8 进程间通信

c++下使用命名管道实现进程间通信

C - 在顶层和底层进程之间进行通信