在C++中使用管道进行父子进程间通信

3

我想解决这个问题,但我无法获取输入信息:

创建一个程序,完成以下操作:

1.创建一个父进程和一个子进程

2.父进程从键盘读取一个数字,并将其发送给子进程

3.子进程计算给定的数字是否为质数,并在屏幕上打印结果

这是我的代码:

#include <iostream>
#include <unistd.h>      // for fork()
#include <string.h>      // for strerror()
#include <sys/wait.h>
#include <sys/types.h>

using namespace std;

bool isprime(int number);

int main() 
{
    int num;
    pid_t pid;
    int fd[2];
    char buffer[100];
    pipe(fd);

    pid = fork();
    
    //parent process
    if (pid > 0)
    {
        cin>>num;
        write(fd[1], &num, sizeof(num));
        close(fd[1]);
        int status;
        //Do not check for errors here
        wait(&status);
    }
    //child process
    else if (pid == 0)
    {
        read(fd[0], buffer, 100);
        close(fd[0]);
        if (isprime(num))
        {
            cout<<"number is prime";
        }
        else
        {
            cout<<"number is not prime";
        }
        return EXIT_SUCCESS;
    }
    
    else
    {
        cout << "fork() failed (" << strerror(errno) << ")" << endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;

}
bool isprime(int number)
{
    if (number < 2)
        return false;

    if (number == 2)
        return true;

    for (int i = 2; (i*i) <= number; i++)
    {
        // Take the rest of the division
        if ((number % i) == 0)
            return false;
    }

    return true;
}

这是我的运行结果


@Gal,那不是read函数的工作方式… 它应该返回 4 字节。 - user253751
当你运行它时会发生什么? - user253751
当我运行程序时,它没有采用 num 的输入值。它取代了输入值为“1”的值。这就是为什么它计算值为“1”的原因。 - Zuhriddin Musabayev
1个回答

2

使用管道(pipe)与fork一起编程并不难,但是必须遵守以下规则:

  • 每个部分应该关闭不使用的句柄。不这样做将成为未来问题的关键
  • 从fork开始,一个进程中的更改不会反映到另一个进程中

你的代码应该如下:

...
//parent process
if (pid > 0)
{
    close(fd[0]);   // close the part that only the other process will use
    cin>>num;
    write(fd[1], &num, sizeof(num));
    close(fd[1]);
    int status;
    //Do not check for errors here
    wait(&status);
}
//child process
else if (pid == 0)
{
    close(fd[1]);     // close the part used by the other process
    read(fd[0], &num, sizeof(num)); // read into num what the parent has written
    close(fd[0]);
    ...

在实际的代码中,您应该检查每次读取是否成功(无论是从cin还是管道中...)


你对代码进行了重要的更改,但没有解释清楚(即,读取num而不是读取buffer,而没有分配/写入num)。 - 1201ProgramAlarm
@1201ProgramAlarm:我希望从我的评论中可以清楚地看出,父级别的更改并没有反映在子级别中... 老实说,我无法猜测为什么OP在这里使用缓冲区,所以我也无法解释为什么他们不应该这样做... - Serge Ballesta
但是这些更改并没有改变结果。 - Zuhriddin Musabayev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接