我刚刚开始使用UNIX FIFO,我在尝试第一个FIFO程序时发现了一些东西。程序以这种方式工作:创建FIFO后,使用fork()
函数启动两个进程。子进程读取父亲通过FIFO传递给他的内容,并将其打印在屏幕上。交换的数据是指定为参数的字符串。问题是:在父节中,如果我忘记关闭FIFO的输入端(意味着我排除close(fd)
行),即使正确交换进程之间的数据,程序也会挂起。否则,一切正常,程序终止而不挂。有人可以解释一下为什么吗?
感谢您的耐心等待。这是主要功能的代码:
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("An argument must be specified\n");
return -1;
}
int ret = mkfifo("./fifo.txt", 0644);
char buf;
if(ret < 0)
{
perror("Error creating FIFO");
return -1;
}
pid_t pid = fork();
if(pid < 0)
{
perror("Error creating child process");
return -1;
}
if(pid == 0) /* child */
{
int fd = open("./fifo.txt", O_RDONLY); /* opens the fifo in reading mode */
while(read(fd, &buf, 1) > 0)
{
write(STDOUT_FILENO, &buf, 1);
}
write(STDOUT_FILENO, "\n", 1);
close(fd);
return 0;
}
else /* father */
{
int fd = open("./fifo.txt", O_WRONLY); /* opens the fifo in writing mode */
write(fd, argv[1], strlen(argv[1]));
close(fd);
waitpid(pid, NULL, 0);
return 0;
}
}
答案 0 :(得分:5)
read(2)
阻止,直到有可用字符或通道在另一端关闭。父进程必须关闭管道才能返回最后一个子read()
。如果省略父亲中的close(fd)
,孩子将在read()
中阻止,直到父亲退出(自动关闭管道),但父亲将在waitpid()
中挂起,直到孩子退出。 / p>
答案 1 :(得分:0)
首先要做的事情是:您发布的代码有几个问题。
#include
指令,因此您调用的任何函数的范围都没有原型。 C89需要可变函数的原型,例如printf()
; C99需要所有功能的原型。 C89和C99都要求O_RDONLY
,O_WRONLY
,STDOUT_FILENO
和NULL
的范围内的声明。-1
不是main()
允许的返回值。未成年人:通常的命名法是“父母和孩子”,而不是“父亲和孩子”。
我修改了您的程序以纠正此问题并提高可读性:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
if (argc != 2) {
printf("An argument must be specified\n");
return 1;
}
int ret = mkfifo("./fifo.txt", 0644);
char buf;
if (ret < 0) {
perror("Error creating FIFO");
return 1;
}
pid_t pid = fork();
if (pid < 0) {
perror("Error creating child process");
return 1;
}
if (pid == 0) { /* child */
int fd = open("./fifo.txt", O_RDONLY); /* opens the fifo in reading mode */
while(read(fd, &buf, 1) > 0) {
write(STDOUT_FILENO, &buf, 1);
}
write(STDOUT_FILENO, "\n", 1);
close(fd);
return 0;
} else { /* parent */
int fd = open("./fifo.txt", O_WRONLY); /* opens the fifo in writing mode */
write(fd, argv[1], strlen(argv[1]));
close(fd);
waitpid(pid, NULL, 0);
return 0;
}
}
但最重要的是,你没有提到你正在使用的操作系统和编译器。
我无法重现该问题,我怀疑它可能与上面列出的问题之一有关。