我想创建一个简单的程序,即fork,并且子进程写入命名管道,父进程从命名管道读取和显示。 问题是它进入了父进程,进行了第一次printf然后它变得奇怪,它没有做任何其他事情,没有进入第二个printf,它只是在控制台中输入的方式。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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);
}
}
答案 0 :(得分:5)
您确实应该检查函数调用的返回值是否有错误,尤其是mkfifo()
和open()
。
您对wait()
的来电将导致其当前位置出现问题。打开FIFO以便正常读取块,直到某个其他进程打开相同的FIFO进行写入,反之亦然 1 。父母正在等待孩子终止,孩子正在等待读者进程(即父母)连接到FIFO。
1 - 请参阅下面open()
的说明,了解O_NONBLOCK
使用FIFO
将wait()
来电转移到父流程退出之前,同时将调用中的模式更改为mkfifo()
至0666
似乎可以解决您的一些直接问题。
完成后删除FIFO也是一种好习惯。
unlink("myfifo");
来自open()
function documentation in IEEE Std 1003.1-2004:
使用O_RDONLY或O_WRONLY设置打开FIFO时:
如果设置了O_NONBLOCK,则只读的open()应无延迟返回。如果当前没有任何进程打开文件进行读取,则open()仅写入将返回错误。
如果O_NONBLOCK被清除,则只读的open()将阻塞调用线程,直到线程打开文件进行写入。只写的open()将阻塞调用线程,直到线程打开文件进行读取。
以下示例是code in your original question和FIFO page of Beej's Guide to Unix IPC:
的组合#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#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中测试过。按 Ctrl - D 终止程序。
答案 1 :(得分:3)
首先,尝试fprintf到stderr而不是printf(到stdout)
stderr没有缓冲。
然后你就可以知道实际打印的内容和不打印的内容。
或至少在等待任何事情之前添加fflush
。