我需要这个示例应用程序的帮助。当我运行它时,它会在子进程打印出“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会自动转到父进程
答案 0 :(得分:4)
在孩子写入父母之后,它必须关闭管道的写入结束,以便父母知道它已达到EOF。
答案 1 :(得分:1)
有些不对劲的事情:
fd2
从未初始化。
父母永远不会退出:
while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
{
strncat(buffer, readbuffer,rd);
gd = 1;
}
如果没有要读取的数据,读取将被阻止而不会返回。唯一可以让它退出的是连接是否关闭而且孩子没有关闭它。
答案 2 :(得分:1)
您的代码中存在许多错误。为什么在没有初始化的情况下使用fd2?去掉它。 现在它停留在“Child发送”,因为管道读取是一个阻塞调用,你将它放在一个永远不会返回的while循环中。请参考管道的手册页 如果要在while循环中断开,请关闭该管道的所有写入端。
同样要调试子进程,在调试时调用fork()之前使用gdb命令follow-fork-mode
作为子进程。
答案 3 :(得分:0)
您正在调用read()
,期望如果没有要读取的内容,它将返回零字节读取。但是,您看到的是因为read()
在返回之前正在等待某些数据。要解决这个问题,您需要做以下两件事之一:
select()
或poll()
查看在阅读之前是否有一些数据需要阅读另外,还有其他几点:
malloc()
malloc()
是否未返回NULL
gotdata
指令替换整个break
内容