C命名管道(fifo)。 父进程陷入困境

我想创建一个简单的程序,该fork,并且子进入命名管道,父进程从命名管道读取和显示。 问题是它进入了父进程,进行了第一次printf然后它变得奇怪,它没有做任何其他事情,没有进入第二个printf,它只是在控制台中输入的方式。

#include  #include  #include  #include  #include  #include  #include  void main() { char t[100]; mkfifo("myfifo",777); pid_t pid; pid = fork(); if (pid==0) { //execl("fifo2","fifo2",(char*)0); char r[100]; printf("scrie2->"); scanf("%s",r); int fp; fp = open("myfifo",O_WRONLY); write(fp,r,99); close(fp); printf("exit kid \n"); exit(0); } else { wait(0); printf("entered parent \n"); // <- this it prints // whats below this line apparently its not being executed int fz; printf("1"); fz = open("myfifo",O_RDONLY); printf("2"); printf("fd: %d",fz); char p[100]; int size; printf("------"); //struct stat *info; //stat("myfifo",info); printf("%d",(*info).st_size); read(fz,p,99); close(fz); printf("%s",p); printf("exit"); exit(0); } } 

你真的应该检查函数调用的返回值是否有错误,尤其是mkfifo()open()

您对wait()调用将导致其当前位置出现问题。 打开FIFO以便正常读取块,直到某个其他进程打开相同的FIFO进行写入,反之亦然1 。 父母正在等待孩子终止,孩子正在等待读者进程(即父母)连接到FIFO。

1 – 请参阅下面的open()注释,了解如何使用带有FIFO的O_NONBLOCK

wait()调用移到父进程退出之前以及将调用mkfifo()的模式更改为0666似乎可以解决一些直接问题。

完成后删除FIFO也是一种好习惯。

 unlink("myfifo"); 

从IEEE Std 1003.1-2004中的open()函数文档 :

使用O_RDONLY或O_WRONLY设置打开FIFO时:

  • 如果设置了O_NONBLOCK,则只读的open()应该无延迟地返回。 如果当前没有进程打开文件进行读取,则open()仅写入将返回错误。

  • 如果O_NONBLOCK是清除的,则只读的open()将阻塞调用线程,直到线程打开文件进行写入。 只写的open()将阻塞调用线程,直到线程打开文件进行读取。


以下示例是原始问题中的代码 与Beej的Unix IPC指南的FIFO页面的组合 :

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #define FIFO_NAME "myfifo" int main(void) { char buf[256]; int num, fd; pid_t pid; if (mkfifo(FIFO_NAME, 0666) < 0) perror("mkfifo"); pid = fork(); if (pid == 0) { printf("child - waiting for readers...\n"); if ((fd = open(FIFO_NAME, O_WRONLY)) < 0) perror("child - open"); printf("child - got a reader -- type some stuff\n"); while (fgets(buf, sizeof(buf), stdin), !feof(stdin)) { if ((num = write(fd, buf, strlen(buf))) < 0) perror("child - write"); else printf("child - wrote %d bytes\n", num); } close(fd); exit(0); } else { printf("parent - waiting for writers...\n"); if ((fd = open(FIFO_NAME, O_RDONLY)) < 0) perror("parent - open"); printf("parent - got a writer\n"); do { if ((num = read(fd, buf, sizeof(buf))) < 0) perror("parent - read"); else { buf[num] = '\0'; printf("parent - read %d bytes: \"%s\"\n", num, buf); } } while (num > 0); close(fd); wait(0); } unlink(FIFO_NAME); return 0; } 

此示例在Linux中进行了测试。 按CtrlD终止程序。

首先,尝试fprintf到stderr而不是printf(到stdout)

stderr是无缓冲的。

然后你就可以知道实际打印的内容和不打印的内容。

或者至少在等待之前添加fflush