我正在Linux中学习命名管道并编写以下程序来试用它。
以下程序创建一个名为“test.fifo”的FIFO特殊文件,然后创建两个子进程以从该命名管道进行读写。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wait.h>
int main() {
pid_t pid[2];
// Create FIFO special file
mkfifo("test.fifo", 0644);
pid[0] = fork();
if (pid[0] < 0) {
printf("Fail to fork child process #0\n");
return 1;
} else if (pid[0] == 0) {
// Open FIFO special file in read mode
int in = open("test.fifo", O_RDONLY);
// Read data
char buf[256];
read(in, buf, 256);
printf("Child process #0 received: %s\n", buf);
// Close pipe
close(in);
return 0;
}
pid[1] = fork();
if (pid[1] < 0) {
printf("Fail to fork child process #1\n");
return 1;
} else if (pid[1] == 0) {
// Open FIFO special file in write mode
int out = open("test.fifo", O_WRONLY);
// Write data
char buf[256] = {0};
strcpy(buf, "Hello world");
write(out, buf, 256);
// Close pipe
close(out);
return 0;
}
return 0;
}
有时这个程序运行正常。但有时在这个程序运行后,我的shell提示会消失。
MyUserName@MyHostName:~$ ./a.out
MyUserName@MyHostName:~$ Child process #0 received: Hello world
(This is an empty line, no shell prompt occurs)
我尝试在空行中键入并运行命令ls
,命令有效。因此,程序似乎已成功退出,而且只是shell提示不会发生。
如果我运行命令cat test.fifo
,也会发生同样的事情。
MyUserName@MyHostName:~$ cat test.fifo
(This is an empty line, no shell prompt occurs)
发生了什么,为什么会发生这种情况?
答案 0 :(得分:0)
感谢所有评论!
就像Charles Duffy所说,shell提示已经被打印 - 它是./a.out调用之后的那个。我忘了在父进程中使用wait()
。因此,如果父进程在子进程之前退出,则shell提示符将在“子进程#0 ...”之前打印。
对于cat test.fifo
,我在描述中犯了一个错误。如果我运行cat test.fifo
,不仅不会出现shell提示符,而且如果我在空行上键入并运行它,ls
命令也将无法工作。这是因为cat
命令试图在读模式下打开FIFO特殊文件,但没有进程尝试在写模式下打开FIFO特殊文件。
从https://linux.die.net/man/7/fifo我们知道,“在数据通过之前,FIFO必须在两端打开(读取和写入)。通常,打开FIFO块直到另一端打开。”因此cat test.fifo
命令实际上已被阻止且尚未退出,因此不会发生shell提示。