我有一个非常简单的基本程序,它有两个过程,第一个是parent
,第二个是child
。
子进程应将一些内容写入FIFO
。所有写作业完成之后(终止孩子之后)。
然后,父进程应读取所有FIFO
文件并打印到stdout
。
因此,我认为wait(NULL);
需要一个parent
。因此parent
将等待直到child
被终止。但是child
也因为写而被阻塞,并且由于读此写而被阻塞。因此,这两个过程相互等待,我认为这会发生死锁。
我的程序是这样的:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
int writeSomeStuffToFifo ();
void printAllFifo ();
char * myfifo = "myfifo";
int main(int argc, char **argv) {
int pid=0;
int childPid=-1;
int status;
pid=fork();
if ((pid = fork()) < 0){
perror("fork() error");
}
else if (pid == 0) {
writeSomeStuffToFifo ();
exit(1);
}
else do {
if ((pid = waitpid(pid, &status, WNOHANG)) == -1)
perror("wait() error");
else if (pid == 0) {
//child running
printf("child running\n");
}
else {
if (WIFEXITED(status)){
printf("child is terminated\n");
printAllFifo();
}
else{
printf("child did not exit successfully\n");
}
}
} while (pid == 0);
return 0;
}
int writeSomeStuffToFifo (){ //child process will run this function
int fd;
mkfifo(myfifo, 0666);
fd = open(myfifo, O_WRONLY);
write(fd,"foo1\n",strlen("foo1\n"));
close(fd);
fd = open(myfifo, O_WRONLY);
write(fd,"foo2\n",strlen("foo2\n"));
close(fd);
fd = open(myfifo, O_WRONLY);
write(fd,"foo3\n",strlen("foo3\n"));
close(fd);
}
void printAllFifo (){ //parent process will run this function
int fd=open(myfifo, O_RDONLY);
char* readBuffer=(char*)malloc((strlen("foo1\n")+strlen("foo2\n")+strlen("foo3\n"))*sizeof(char));
read(fd, readBuffer, strlen("foo1\n")+strlen("foo2\n")+strlen("foo3\n"));
printf("%s\n",readBuffer );
close(fd);
}
答案 0 :(得分:3)
mkfifo()
创建一个有限大小的管道。您不应该在父进程中等待直到子进程完成才能阅读,而应该在父进程中不断阅读,同时检查子进程是否已经终止。
您可以使用ulimit -p
来读取Linux系统中管道的默认大小。该数字是512的倍数,因此8的值表示4096个字节。
使用pipe()
比mkfifo()
更适合该任务,因为您实际上不需要命名管道。这将为您提供2个fds,一个用于读取,另一个用于写入。在父代码中,关闭写入fd,在子代码中,关闭读取fd,然后您可以从父代码中的管道开始读取,直到返回值<=0。这意味着子进程已终止(并且该管道已关闭以进行写入)。那么您只需要从父代码调用waitpid()
即可收集终止的子进程。