【发布时间】:2015-12-25 17:33:34
【问题描述】:
我是管道新手,我一直在尝试创建一对管道,允许子进程写入父进程,并让父进程返回通信。有 1 位家长,最多 4 位孩子。子进程通过 exec 成为不同的程序。
我的工作:
从父进程写入子进程。当我读入子程序的标准输入时,它会收到我从父程序写的内容。
目标:
创建一个纸牌游戏,其中父母与每个单独的客户(子进程)交谈,并向他们提供从标准输出到子标准输入的所有动作和信息。各个子进程在其标准输出上返回他们的动作,由主要父进程读取。游戏的动作完全由顺序决定,而不是玩家。所以这是一个机器人游戏。
我的困惑:
我不确定如何获取它,以便父母可以通过文件流读取孩子的标准输出。当我尝试设置从子行读取时,代码似乎停止工作。甚至孩子也不能从父母那里阅读(它似乎停在现在注释掉的用于将孩子设置为父母的留置权上)。
我也不确定如何“等待”直到出现某些东西。就像,一开始玩家必须向父母发送一条“准备就绪”的消息,让他们知道他们正在工作。一旦我从孩子那里发送“就绪”,我如何无限期地“等待”直到下一条消息出现?
我不确定我是否正确设置了管道。有人可以提供有关如何使用通信管道的指导并在下面确认我的逻辑吗?
我收集的让父母写信给孩子的是:
- 先创建管道
- 将父进程分叉到另一个进程(子进程)
- 将管道的输入连接到父级的标准输出,并使用 dup2 关闭父级的读取端并关闭
- 将管道输出连接到孩子的标准输入,并使用 dup2 关闭孩子的书写部分并关闭
- 使用 fdopen() 从文件描述符中获取文件流,然后打印到该文件流。
- 子进程标准输入现在是您从父进程打印到标准输出的任何内容。
这是正确的吗?我尝试将这种针对孩子的逻辑应用于父母,但将其反转。
- 将输入管道连接到读取文件流,这是子程序从其标准输出写入的位置。
-
将输出管道连接到父级读取的读取流。
void start_child_process(Game *game, int position) { int child2Parent[2]; int parent2Child[2]; if (pipe(parent2Child)) { printf("PIPE FAIL!\n"); } if (pipe(child2Parent)) { printf("PIPE FAIL!\n"); } pid_t pid = fork(); game->readStream[position] = fdopen(child2Parent[0], "r"); game->writeStream[position] = fdopen(parent2Child[1], "w"); if (pid) { // Parent // Write from parent to child close(parent2Child[0]); dup2(fileno(game->writeStream[position]), STDOUT_FILENO); fprintf(game->writeStream[position], "%s", "test message"); fflush(game->writeStream[position]); close(parent2Child[1]); // Read from child -- not working /*dup2(child2Parent[0], STDIN_FILENO); close(child2Parent[0]); close(child2Parent[1]); */ } else { // Setup child to read from stdin from parent dup2(parent2Child[0], STDIN_FILENO); close(parent2Child[1]); // Setup writing from child to parent /* if (dup2(child2Parent[1], STDOUT_FILENO) == -1) { fprintf(stderr, "dup2 in child failed\n"); } else { fprintf(stderr, "dup2 in child successful\n"); close(child2Parent[0]); close(child2Parent[1]); } */ if ((int)execl("child", "2", "A", NULL) == -1) { printf("Failed child process\n"); } } }
我的孩子主要有以下内容:
char string[100];
printf("reading from pipe: %s\n", fgets(string, 100, stdin));
但我不确定如何
另外,我不允许使用 popen() 或 write()。显然,我也被鼓励使用文件流。
【问题讨论】: