- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我是管道的新手,一直在尝试创建一对管道,它允许子进程写入父进程,并让父进程返回通信。有 1 位家长最多带 4 个 child 。 child 变成了exec不同的程序。
我的工作:
从父进程写入子进程。当我读入子程序的标准输入时,它会收到我从父程序中写入的内容。
目标:
创建一个纸牌游戏,父进程与每个单独的客户端(子进程)交谈,并向他们提供所有 Action 和信息,从其标准输出到子进程的标准输入。各个子进程在其 stdout 上返回它们的移动,由主要父进程读取。游戏的 Action 完全由顺序决定,而不是玩家。所以这是一个机器人游戏。
我坚持的是:
我不确定如何获取它以便 parent 可以通过文件流读取 child 的标准输出。当我尝试设置从子行读取时,代码似乎停止工作。甚至 child 也不能从 parent 那里读取(它似乎停止在现在被注释掉的用于设置 child 到 parent 的留置权)。
我也不确定如何“等待”直到某些东西出现。比如,一开始玩家必须向 parent 发送一条“准备就绪”消息,让他们知道他们正在工作。一旦我从 child 发送“准备好”,我如何无限期地“等待”直到下一条消息出现?
我不确定我是否正确设置了管道。有人可以提供有关如何使用通信管道的指导并确认我在下面的逻辑吗?
我收集到的让 parent 写给 child 的是:
这是正确的吗?我尝试将这种针对 child 的逻辑应用于 parent ,但将其颠倒过来。
将输出管道连接到父级读取的读取流。
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");
}
}
}
我的 child 主要有以下内容:
char string[100];
printf("reading from pipe: %s\n", fgets(string, 100, stdin));
但是我不知道怎么办
此外,我不允许使用 popen() 或 write()。显然我也被鼓励使用文件流。
最佳答案
我主要针对您在父进程和子进程之间建立双向通信的主要问题发言。如果您需要其他答案,请提出单独的问题。
你似乎有一个合理的通用方法,但你确实有一个严重的误解/设计缺陷:虽然多个客户端将它们的标准流连接到管道以与父进程通信是合理的,但你不能连接父进程的如果您希望一次能够处理多个客户端,则将所有这些管道结束到父级的标准流。毕竟,父级只有一组标准流。为了支持多个客户端,父进程必须为每个客户端维护一对单独的文件描述符和/或流,并且必须通过这些而不是通过其标准流进行通信。
我不确定为什么当你连接子到父方向时你的父/子通信失败。该过程确实类似于设置另一个端点。这是一个工作示例:
父类.c:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int main() {
int child2Parent[2];
int parent2Child[2];
char buffer[256];
FILE *p2cStream;
FILE *c2pStream;
pid_t pid;
if (pipe(parent2Child) || pipe(child2Parent)) {
perror("Failed to create pipes");
exit(EXIT_FAILURE);
}
switch (pid = fork()) {
case -1: /* error */
perror("Failed to fork");
break;
case 0: /* child */
// Setup child to read from stdin from parent
close(parent2Child[1]); /* ignoring any error */
close(child2Parent[0]); /* ignoring any error */
if ((dup2(parent2Child[0], STDIN_FILENO) < 0)
|| (dup2(child2Parent[1], STDOUT_FILENO) < 0)) {
perror("Failed to duplicate file descriptors");
} else {
/* conventionally, the first program argument is the program name */
/* also, execl() returns only if it fails */
execl("child", "child", "2", "A", NULL);
perror("Failed to exec child process");
}
exit(EXIT_FAILURE);
break;
default: /* parent */
close(parent2Child[0]); /* ignoring any error */
close(child2Parent[1]); /* ignoring any error */
if (!(p2cStream = fdopen(parent2Child[1], "w"))
|| !(c2pStream = fdopen(child2Parent[0], "r"))) {
perror("Failed to open streams");
exit(EXIT_FAILURE);
}
if ((fprintf(p2cStream, "test message from parent\n") < 0)
|| fclose(p2cStream)) {
perror("Failed to write to the child");
exit(EXIT_FAILURE);
}
if (fscanf(c2pStream, "%255[^\n]", buffer) < 1) {
perror("Failed to read the child's message");
exit(EXIT_FAILURE);
}
printf("The child responds: '%s'\n", buffer); /* ignoring any error */
break;
}
return EXIT_SUCCESS;
}
child .c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
char buffer[256] = { 0 };
if (scanf("%255[^\n]", buffer) < 0) {
perror("Failed to reading input");
exit(EXIT_FAILURE);
}
/*
* If stdout is connected to the parent then we must avoid
* writing anything unexpected to it
*/
if (fprintf(stderr, "received: '%s'\n", buffer) < 0) {
perror("Failed to echo input");
exit(EXIT_FAILURE);
}
printf("Hi, Mom!\n"); /* ignoring any error */
fflush(stdout); /* ignoring any error */
return EXIT_SUCCESS;
}
对比你的代码,请注意
execl()
参数的约定。另请注意,对于等待某物“出现”而言,以这种方式设置的 IPC 流上的 I/O 操作将自动产生该效果。然而,您如何能够或应该如何利用它肯定是一个不同的问题。
关于c - 了解管道、重定向和 IPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32823609/
我的主要流程(重要代码): let introWindow let win = null function createWindow() { // Create the browser win
信号量是一种 IPC 机制吗? 最佳答案 是的,在许多平台下,信号量可以跨进程同步。您将为此使用“命名”信号量——多个进程通过名称访问对象,类似于文件系统对象。 在 POSIX 中,您可以通过 sem
我一直在关注 Thrift 对 Windows 和 VS 开发的支持,感谢许多贡献者,它已经取得了长足的进步。有针对编译器和 C++ 库的 VS 2010 项目,我已经确认它们在 0.8 中运行良好。
或者它们是同义词吗? 最佳答案 维基百科通常非常适合这些目的。 RPC: Remote procedure call (RPC) is an Inter-process communication t
是否有标准库的一部分? 我一直在四处挖掘,但我看不到任何明显的实现它的东西,或者在 Process 上的任何东西可以让你这样做? 我错过了吗?还是我必须为此功能做一些 C 包装器工作? (如果是这样,
我计划在同一主机上运行的两个进程之间为我的 IPC(进程间通信)使用 unix 域套接字。但在选择 unix 套接字之前,我还必须研究数据安全性。 我只是想知道如果我使用 unix 套接字而不加密我在
System V IPC 和 POSIX IPC 之间有什么区别? 为什么我们有两个标准? 如何决定使用哪些 IPC 函数? 最佳答案 两者都有相同的基本工具——信号量、共享内存和消息队列。它们提供的
在我的menu.js中的“label:'Database'”下,单击事件返回错误:ipc未定义。我想,如果这是 main.js 文件的一部分,并且如果我已经在全局范围内声明了一个 const 为 ip
我正在设置两个 docker 容器 - 一个作为服务器在内存中保存数据,另一个作为客户端访问该数据。为此,我相信我需要使用 --ipc在容器之间共享内存的标志。 Docker documentatio
我正在尝试使用来自 HDFS 的文件运行 flink 作业。我创建了一个数据集如下 - DataSource> visits = env.readHadoopFile(new TextInputFor
我在 NetBeans IDE 8.0.2 中使用 hadoop 2.7.0 和 java oracle jdk1.7.0_79。当我尝试使用 Java 文件与 Hadoop 通信时,出现以下错误。是
我一直在使用 Electrons 同步和异步 RPC 通信机制,并且可以很好地在进程之间传递我的数据。但是,我现在需要不断地向渲染器进程发送事件数据(有点像聊天应用程序)并更新一些文本。 这在 Ele
我正在用 Go 编写一个负载平衡的服务器系统。 负载平衡服务器将与多个应用服务器通信并处理请求。这些服务器既可以在同一台机器上运行,也可以在网络上运行。 我已经弄清楚了网络,但现在我需要为负载均衡器找
我有一个关于操作系统中进程间通信的问题。 两个进程是否可以通过打开同一个文件(据说是在两个进程之前创建的,所以两个进程都有文件处理程序)然后通过写入该文件进行通信来相互通信? 如果是,这个方法属于什么
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 6年前关闭。
我有一个使用 System V 共享内存段的应用程序。通常它在内部管理这些,没有人需要接触它们。但对于紧急情况,我们有一个实用程序可以手动清除共享内存段。 问题是,为了做到这一点,它运行ipcs,并使
当使用node-ipc通过IPC在NodeJS进程之间进行通信时,启动服务器并监听连接,或者创建客户端并连接到服务器似乎非常简单。 但是有些事情看起来并不那么简单: How can the serve
我正在寻找有关我可以在我自制的 AVR32 板操作系统中实现的可能 IPC 机制的建议。 我目前的选择是实现 Tanenbaum 所写书籍中描述的按摩传递机制。 这是一个不错的选择吗?有没有更简单的方
我去面试了。面试官问我: If two nodes are sending two messages of the same identifier (0x100) with different dat
我正在寻找一种进程间通信工具,可以在相同或不同系统上运行的语言和/或环境之间使用。例如,它应该允许在 Java、C# 和/或 C++ 组件之间发送信号,并且还应该支持某种排队机制。唯一明显与环境和语言
我是一名优秀的程序员,十分优秀!