【发布时间】:2020-05-15 11:46:37
【问题描述】:
这个问题已经有多个答案,但没有一个能够帮助我解决我的问题。我正在尝试使用 C 中的匿名管道来理解 IPC。
根据我对管道的理解,它们是一种单向通信通道,具有一个读端和一个写端。
假设我们有两个 c 文件,一个名为 parent.c,另一个名为 child.c。我想要实现的是能够创建 5 个或更多子进程。在此之后,父进程和子进程应该通过标准输入和standard output 与子进程通信,但是由于我希望能够打印父进程从子进程接收到的内容,因此我将使用管道将管道连接到standard error 输出dup2。
总结
1. 运行一个启动 5 个或更多子进程并运行它们的父程序。
2. 子进程使用scanf等待父进程的输入。
3.父进程向子进程发送消息。
4.子进程收到消息,向父进程发送回复并退出。
5.父进程打印接收到的消息,打印后退出。
parent.c
// Parentc
#include <stdio.h>
#include <stdlib.h>
#include <uinstd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, const char *argv[]){
// File descriptors for the pipes
int read_pipe[2]; // From child to parent
int write_pipe[2]; // From parent to child
pid_t process_id;
int exit_status;
// Try to fork 5 child processes
for(int i = 0; i < 5; i++){
if(pipe(write_pipe) == -1 || pipe(read_pipe) == -1){
perror("Pipe");
exit(1);
}
// Spin a child process
process_id = fork();
if(process_id == -1){
perror("Fork");
exit(1);
} else if(processId == 0) {
// The child process
// I don't know what to do here, The idea is to close the
// unneeded end of the pipes and wait for input from the parent
// process
// Start the ./child
execl("./child", "");
} else {
// The parent process
char recieved_data[1024];
// Send data to child since stderr is duplicated in the pipe
// It sends the pid of the child
fprintf(stderr, "Test data to %d ", process_id);
// Wait to recieve data from child
// Don't know how to do that
// Print the recieved data
printf("Parent recieved: \"%s\"\n", recieved_data);
wait(&exit_status); // Will wait till all children exit before exiting
}
}
return 0;
}
child.c 是一个如下所示的简单程序
child.c
#include <stdio.h>
int main(int argc, const char *argv[]){
char data_buffer[1024];
// Wait for input from parent
scanf("%s", data_buffer);
// Send data back to parent
printf("Child process: %s", data_buffer);
return 0;
}
预期输出
$ ./parent
parent recived: "Child process: Test data to 12345"
parent recived: "Child process: Test data to 12346"
parent recived: "Child process: Test data to 12347"
parent recived: "Child process: Test data to 12348"
parent recived: "Child process: Test data to 12349"
其中12345、12346....12349是子进程的进程id
【问题讨论】:
-
你没有使用
dup... -
@Jean-BaptisteYunès 那是因为我不完全理解它是如何工作的。我可以
dup2(write_pipe[1], STDIN_FILENO);但是管道的哪一端要复制,哪一端不要关闭是我不明白的 -
否
write_pipe[1]是管道的写入部分,因此请不要将其重定向到应该读取的内容。dup2(write[1],STDOUT_FILENO);可以解决问题,之后写入STDOUT_FILENO将写入管道。 -
谢谢。对此,我真的非常感激。经过一些错误,它终于可以正常工作了。
标签: c linux multithreading pipe ipc