fork()和pipe()

问题描述 投票:0回答:4

我需要此示例应用程序的帮助。当我运行它时,它在子进程打印“Child Sending!”后卡住了。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>

#define INPUT 0
#define OUTPUT 1
int main()
{
    int fd1[2];
    int fd2[2];
    int pid;
    if (pipe(fd1) < 0)
        exit(1);
    if (pipe(fd2) < 0)
        exit(1);
    if ((pid = fork()) < 0)
    {
        perror("fork");
        exit(1);
    }
    else if (pid == 0)
    {
        close(fd1[INPUT]);
        close(fd2[OUTPUT]);
        char *str = "Hello World!";
        printf("Child sending!\n");
        write(fd1[OUTPUT], str, strlen(str));
        char *bufferc = (char *)malloc(1000);
        char *readbufferc = (char *)malloc(80);
        int rdc;
        int gotdata = 0;
        while (gotdata == 0)
             while ((rdc = read(fd2[INPUT], readbufferc, sizeof(readbufferc))) > 0)
             {
               strncat(bufferc,readbufferc,rdc);
               gotdata = 1;
             }
        printf("Child received: %s",bufferc);
        free(readbufferc);
        free(bufferc);
        exit(0);
    }
    else
    {
        close(fd1[OUTPUT]);
        close(fd2[INPUT]);
        int rd;
        char *buffer = (char *)malloc(1000);
        char *readbuffer = (char *)malloc(80);
        int gd = 0;
        while (gd == 0)
             while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
             {
               strncat(buffer, readbuffer,rd);
               gd = 1;
             }
        printf("Parent received: %s\n",buffer);
        free(readbuffer);
        printf("Parent sending!");
        write(fd2[OUTPUT], buffer, strlen(buffer));
        free(buffer);
    }
    return 0;
}

顺便说一句,当我使用fork时,有没有办法进行调试,因为GDB会自动转到父进程?

c fork pipe
4个回答
4
投票

子进程向父进程写入数据后,必须关闭管道的写入端,以便父进程知道它已达到 EOF。


1
投票

您的代码中有很多错误。为什么使用 fd2 而不初始化它?去掉它。 现在它陷入了“子发送”状态,因为管道读取是一个阻塞调用,并且您将其放入一个永远不会返回的 while 循环中。请参阅管道的手册页。
如果您想中断 while 循环,请关闭该管道的所有写入端。

还要调试子进程,请在调试时调用 fork() 之前使用 gdb 命令

follow-fork-mode
作为子进程。


1
投票

有几处错误:

  • fd2
    只是从未初始化过。

  • 家长永远不会退出这个:

    while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
    {
        strncat(buffer, readbuffer,rd);
        gd = 1;
    }
    

如果没有数据要读取,read将会阻塞并且不返回。唯一让它退出的是连接被关闭并且子进程没有关闭它。


0
投票

您调用

read()
的期望是,如果没有任何内容可读取,它将返回读取的零字节。然而,您所看到的是因为
read()
在返回之前正在等待一些数据。要解决此问题,您需要执行以下两件事之一:

  • 将套接字设置为执行非阻塞读取(不推荐)
  • 读取之前先用
    select()
    poll()
    查看是否有数据需要读取

还有其他几点:

  • 不要投射
    malloc()
  • 的回报
  • 检查
    malloc()
    是否不返回
    NULL
  • 将整个
    gotdata
    内容替换为
    break
    指令
© www.soinside.com 2019 - 2024. All rights reserved.