【发布时间】:2013-02-01 17:42:03
【问题描述】:
我需要编写具有这样结构的程序:
父母先做fifo,然后fork()
- child 1 从标准输入读取消息并将其写入命名管道 (FIFO)
- 然后在父进程中我需要创建管道(未命名)和另一个
fork() - 子编号 2 从 FIFO 中读取,计算消息长度并通过管道(未命名)将编号发送给父编号。
我用一个 fork 创建了一个简单的程序,孩子可以与父母交流:
#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
所以在父 1 中我打开 FIFO 进行读取,在子 1 中我正在写入 FIFO,子 2 应该读取它。我的意思是在代码中,因为当我运行它时,我什至无法向 FIFO 写入任何内容。在 scanf("%s", writer); 的块中,它在第一个程序中起作用。
我是否正确使用open()?我需要在某处使用getpid() 吗?为什么当我尝试写入 fifo 时它会阻塞。
【问题讨论】:
-
您好,您不测试第二次分叉是否成功。如果它失败了, printf 不会发生并且 scanf 会挂起......也许你就是这种情况?此外,open(FIFO, 0_RDONLY) 发生在 PARENT1 和 CHILD2 上,在 PARENT1 上似乎没有必要。
-
我为第二个分叉添加了测试。关于 PARENT1 中的 open(FIFO, O_RDONLY):我需要它,因为当我没有写入 CHILD1 中的 fifo 时出错(没有人打开 fifo 进行读取)... 编辑:我从 PARENT1 中删除了 open,在 CHILD1 中我更改了pipe_fd = open(FIFO, O_WRONLY | O_NONBLOCK);到 pipe_fd = open(FIFO, O_WRONLY);现在它不从键盘读取,而是写入屏幕空阅读器数组...