繁体   English   中英

fork()和pipe()

[英]fork() and pipe()

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

#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自动转到父进程

子代写给父代后,它必须关闭管道的写端,以便父代知道它已到达EOF。

有几处错误:

  • fd2从未被初始化。

  • 父母永远不会退出:

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

如果没有要读取的数据,则读取将阻塞并且仅不返回。 使连接退出的唯一一件事是,如果连接已关闭并且孩子没有将其关闭。

您的代码中有很多错误。 为什么在未初始化的情况下使用fd2? 去掉它。 现在,由于“管道读取”是一个阻塞调用,您将其置于“永不返回”的while循环中,因此它一直停留在“发送子进程”上。 请参考管的手册页。
如果要中断while循环,请关闭该管道的所有写端。

同样,为了调试子进程,在调试时调用fork()之前,请使用gdb命令follow-fork-mode作为子进程。

您正在调用read()的期望是,如果没有要读取的内容,它将返回读取的零字节。 但是,您看到的是因为read()在返回之前正在等待一些数据。 要解决此问题,您需要执行以下两项操作之一:

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

另外,还有其他几点:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM