在C中是否可以有多个并发的一对一管道? 我的示例用例如下:
我目前的尝试草案如下,但是我对它的功能有疑问:
// Create x pipes
int fd[2*x];
pipe(fd);
// In child i do (i from 0 to x-1 inclusive):
close(fd[2*i]);
write(fd[2*i +1], .....);
close(fd[2*i +1]);
// In parent do:
wait() // wait for children to finish
// while any pipe has content do:
// For each i from 0 to x-1 inclusive:
close(fd[2*i +1]);
read(fd[2*i], .....);
close(fd[2*i]);
如果有人可以向我展示这个概念的简单示例,我将不胜感激。这里的最终目标是在子代与父代之间进行对话的一种方式,父代将把多个值存储到单个数组中。
答案 0 :(得分:1)
此代码或多或少地满足您的要求。它使用错误报告代码,该代码在GitHub上的SOQ(堆栈溢出问题)存储库中以src/libsoq子目录中的文件stderr.c
和stderr.h
的形式提供。
#include "stderr.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
enum { NUM_CHILDREN = 5 };
enum { MSG_BUFFSIZE = 64 };
static void be_childish(int kid, int *fd);
int main(int argc, char **argv)
{
int fd[2 * NUM_CHILDREN];
int pid[NUM_CHILDREN];
err_setarg0(argv[0]);
err_setlogopts(ERR_PID);
if (argc != 1)
err_usage("");
for (int i = 0; i < NUM_CHILDREN; i++)
{
if (pipe(&fd[2 * i]) != 0)
err_syserr("failed to create pipe for child %d: ", i);
}
for (int i = 0; i < NUM_CHILDREN; i++)
{
if ((pid[i] = fork()) < 0)
err_syserr("failed to fork child %d: ", i);
else if (pid[i] == 0)
be_childish(i, fd);
else
{
printf("Child %d has PID %d\n", i, pid[i]);
fflush(stdout);
}
}
char buffer[MSG_BUFFSIZE];
for (int i = 0; i < NUM_CHILDREN; i++)
{
close(fd[2 * i + 1]);
int pipe_in = fd[2 * i + 0];
int nbytes = read(pipe_in, buffer, sizeof(buffer));
if (nbytes < 0)
err_syserr("failed to read from FD %2d: ", pipe_in);
printf("Got %2d bytes [%.*s] from FD %2d, PID %d\n",
nbytes, nbytes, buffer, pipe_in, pid[i]);
close(pipe_in);
}
for (int i = 0; i < NUM_CHILDREN; i++)
{
int status;
int corpse = wait(&status);
if (corpse > 0)
printf("Child with PID %d exited with status 0x%.4X\n", corpse, status);
else
err_syserr("Failed to wait for dead children: ");
}
return 0;
}
static void be_childish(int kid, int *fd)
{
for (int i = 0; i < kid; i++)
{
close(fd[2 * i + 0]);
close(fd[2 * i + 1]);
}
close(fd[2 * kid + 0]);
int estat = kid + 32;
char buffer[MSG_BUFFSIZE];
int nbytes = snprintf(buffer, sizeof(buffer),
"Child %d (PID %d) exiting with status %d",
kid, (int)getpid(), estat);
int pipe_out = fd[2 * kid + 1];
if (write(pipe_out, buffer, nbytes) != nbytes)
err_syserr("failed to write to parent: ");
close(pipe_out);
exit(estat);
}
样品运行:
Child 0 has PID 36957
Child 1 has PID 36958
Child 2 has PID 36959
Child 3 has PID 36960
Child 4 has PID 36961
Got 42 bytes [Child 0 (PID 36957) exiting with status 32] from FD 3, PID 36957
Got 42 bytes [Child 1 (PID 36958) exiting with status 33] from FD 5, PID 36958
Got 42 bytes [Child 2 (PID 36959) exiting with status 34] from FD 7, PID 36959
Got 42 bytes [Child 3 (PID 36960) exiting with status 35] from FD 9, PID 36960
Got 42 bytes [Child 4 (PID 36961) exiting with status 36] from FD 11, PID 36961
Child with PID 36960 exited with status 0x2300
Child with PID 36959 exited with status 0x2200
Child with PID 36958 exited with status 0x2100
Child with PID 36957 exited with status 0x2000
Child with PID 36961 exited with status 0x2400