我需要编写具有这样结构的程序:
家长制作fifo,然后fork()
fork()
我用一个fork创建了一个简单的程序,其中child可以与父进行通信:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO "/tmp/my_fifo"
int main()
{
pid_t fork_result;
int pipe_fd;
int res;
char writer[3];
char reader[3];
res = mkfifo(FIFO,0777);
if (res == 0)
{
printf("FIFO created!\n");
fork_result = fork();
if (fork_result == -1)
{
fprintf(stderr, "fork error");
exit(EXIT_FAILURE);
}
if (fork_result == 0)
{
printf("CHILD 1\n");
pipe_fd = open(FIFO, O_WRONLY | O_NONBLOCK);
scanf("%s", writer);
res = write(pipe_fd,writer,3);
if (res == -1)
{
fprintf(stderr,"error writing fifo\n");
exit(EXIT_FAILURE);
}
(void)close(pipe_fd);
exit(EXIT_SUCCESS);
}
else
{
printf("PARENT\n");
pipe_fd = open(FIFO, O_RDONLY);
res = read(pipe_fd, reader, 3);
printf("reader: 0: %c\n",reader[0]);
printf("reader: 1: %c\n",reader[1]);
printf("reader: 2: %c\n",reader[2]);
(void)close(res);
}
}
else
{
printf("deleting fifo... run program again!\n");
unlink(FIFO);
}
exit(EXIT_SUCCESS);
}
它运作良好。所以我创建了具有上述架构的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO "/tmp/my_fifo"
int main()
{
pid_t fork_result;
pid_t fork_result2;
int pipe_fd;
int res;
char writer[3];
char reader[3];
res = mkfifo(FIFO,0777);
if (res == 0)
{
printf("FIFO created!\n");
fork_result = fork();
if (fork_result == -1)
{
fprintf(stderr, "fork error");
exit(EXIT_FAILURE);
}
if (fork_result == 0)
{
printf("CHILD 1\n");
pipe_fd = open(FIFO, O_WRONLY | O_NONBLOCK);
scanf("%s", writer);
res = write(pipe_fd,writer,3);
if (res == -1)
{
fprintf(stderr,"error writing to fifo\n");
exit(EXIT_FAILURE);
}
(void)close(pipe_fd);
exit(EXIT_SUCCESS);
}
else
{
printf("PARENt 1\n");
//don't forget pipe!
fork_result = fork();
pipe_fd = open(FIFO, O_RDONLY);
if (fork_result == 0)
{
printf("CHILD 2\n");
res = read(pipe_fd, reader, 3);
printf("Odczytano: 0: %c\n",reader[0]);
printf("Odczytano: 1: %c\n",reader[1]);
printf("Odczytano: 2: %c\n",reader[2]);
(void)close(res);
}
}
}
else
{
printf("deleting fifo\n");
unlink(FIFO);
}
exit(EXIT_SUCCESS);
}
运行顺序如下:
PARENT 1
CHILD 1
CHILD 2
所以在Parent 1中我打开FIFO来读取,在子节点1中我正在写入FIFO而子节点2应该读取它。我的意思是在代码中,因为当我运行它时,我甚至无法向FIFO写入任何内容。在scanf("%s", writer);
中用于第一个程序的块中。
我正确使用open()
吗?我需要在某个地方使用getpid()
吗?当我尝试写入fifo时为什么会阻塞。
答案 0 :(得分:1)
问题是CHILD1正在使用O_NONBLOCK
打开fifo,如果没有其他进程打开fifo进行读取,则会失败(使用EWOULDBLOCK
或EAGAIN
)。现在在第一个程序中,父进程在fork之后继续运行并在子进程之前打开fifo进行读取并打开写入结束,因此它可以工作。但是在第二种情况下,父母首先做一个额外的分叉,这使得它减慢到足以使CHILD1在PARENT或CHILD2打开fifo进行读取之前进入其打开命令,因此CHILD1打开失败。
摆脱O_NONBLOCK
并且它工作得很好(尽管你打开了用于阅读PARENT和CHILD2的fifo,这可能不是你想要的)。
如果您想从键盘上读取,还有其他问题。如果你从shell运行它,PARENT将立即退出(或多或少),所以shell将返回从键盘读取命令,这意味着CHILD1和shell将争夺输入。另一方面,如果您执行最初描述的内容并让PARENT从CHILD2的管道中等待读取,它应该按照您的要求执行。
答案 1 :(得分:0)
是不是因为你使用两次相同的变量fork_result?当你创建另一个你不使用的变量fork_result2时,它可能是无意的。
我不知道这是否会解决您的问题,但至少在第二个分叉使用fork_result2会让它更容易理解......