C 使用管道与 parent 的孩子沟通
C Communicate childrens with parent using pipes
我的程序创建与用户输入参数一样多的 children。我在将消息发送到 parent 时遇到问题。我希望每个 child 都使用管道向 parent 发送消息。我不知道怎么做。我知道它如何适用于一个 child:http://tldp.org/LDP/lpg/node11.html 但不知道如何适用于许多人。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
pid_t pid;
if(argc < 3)
{
printf("Not enought arguments");
exit(0);
}
int number = atoi(argv[2]); // number of childern
pid_t pids[number],pid_s;
int i,n=number,status;
int pipes[number*2];
char buff[512];
int r=0,w=0,rr=0,ww=0;
for(i=0; i<n; i++)
{
if(pipe(pipes+(i*2)) < 0)
{
perror("failed to allocate pipes");
}
}
if(strcmp("-p", argv[1]) == 0)
{
//
}
if(strcmp("-f", argv[1]) == 0)
{
//
}
switch (pid = fork()) {
case -1:
perror("Error in fork");
exit(0);
break;
case 0:
for(i=0; i < n; i++)
{
if((pids[i] = fork()) < 0)
{
perror("error fork");
}
else if(pids[i] == 0)
{
close(pipes[0+r]);
char *reply = "message";
int val = getpid();
write(pipes[1+w], &val, strlen(reply)+1);
r+=2;
w+=2;
printf("Stworzylem dziecko z numerem: %d \n", getpid());
execvp(argv[0],NULL);
}
}
while(n > 0)
{
pid_s = wait(&status);
--n;
}
break;
default:
for(i=0; i<n; i++)
{
close(pipes[1+rr]);
int n;
read(pipes[0+ww],&n,sizeof(n));
printf("Wiadomosc: %d \n", n);
rr+=2;
ww+=2;
}
if(wait(0) == -1)
{
}
break;
}
return 0;
}
我要程序创建N children。
每个 child 都必须向 parent 发送一条消息。我使用 exec 任务是因为在我的任务中写到每个 child 都应该作为一个单独的程序运行。我创建了一个示例流,但它不起作用。
目前程序创建了 N childs 个进程。从 child 到 parent 的通信过程无效。
编辑:
对我来说发送和接收数据总是通过同样的事情。我发送进程的 PID,但总是选择相同的。
管道是解决此问题的极其不合适的工具,因为它们基本上是一对一的通信方法。您需要的是多对一的通信方式。为此,我建议使用 message queue。这将允许您的 parent 订阅消息队列并允许无限数量的 children 写入它,并且他们的消息全部被多路复用到 parent.
我无法了解您要对 double-fork 业务进行的操作。
我不想为你写完整的东西,但这里是我将如何编写代码的大纲:
int * pids;
int * fds;
int pipefds[2];
char * message = "message";
int alive = 0;
pids = malloc(n * sizeof(int *));
fds = malloc(n * sizeof(int *));
for (i = 0; i < n; ++i) {
if (pipe(pipefds) == -1) exit(1);
switch (pid = fork()) {
case -1: /* error */
exit(2);
case 0: /* child */
close(pipefds[0]);
write(pipefds[1], message, strlen(message)+1);
_exit(0);
default: /* parent */
closefds[1];
pids[i] = pid;
fds[i] = pipefds[0];
++alive;
}
}
while (alive > 0) {
/* select on the fds[] of all alive (fds[i] != -1) children */
/* if EINTR, do waitpid(-1, &status, WNOHANG); */
/* to see if a child has exited */
/* if so, find it in pids, say at index 'x', and: */
/* close(fds[x]); fds[x] = -1; --alive; */
/* if select said I/O ready for a pipe */
/* then read that pipe */
}
我的程序创建与用户输入参数一样多的 children。我在将消息发送到 parent 时遇到问题。我希望每个 child 都使用管道向 parent 发送消息。我不知道怎么做。我知道它如何适用于一个 child:http://tldp.org/LDP/lpg/node11.html 但不知道如何适用于许多人。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
pid_t pid;
if(argc < 3)
{
printf("Not enought arguments");
exit(0);
}
int number = atoi(argv[2]); // number of childern
pid_t pids[number],pid_s;
int i,n=number,status;
int pipes[number*2];
char buff[512];
int r=0,w=0,rr=0,ww=0;
for(i=0; i<n; i++)
{
if(pipe(pipes+(i*2)) < 0)
{
perror("failed to allocate pipes");
}
}
if(strcmp("-p", argv[1]) == 0)
{
//
}
if(strcmp("-f", argv[1]) == 0)
{
//
}
switch (pid = fork()) {
case -1:
perror("Error in fork");
exit(0);
break;
case 0:
for(i=0; i < n; i++)
{
if((pids[i] = fork()) < 0)
{
perror("error fork");
}
else if(pids[i] == 0)
{
close(pipes[0+r]);
char *reply = "message";
int val = getpid();
write(pipes[1+w], &val, strlen(reply)+1);
r+=2;
w+=2;
printf("Stworzylem dziecko z numerem: %d \n", getpid());
execvp(argv[0],NULL);
}
}
while(n > 0)
{
pid_s = wait(&status);
--n;
}
break;
default:
for(i=0; i<n; i++)
{
close(pipes[1+rr]);
int n;
read(pipes[0+ww],&n,sizeof(n));
printf("Wiadomosc: %d \n", n);
rr+=2;
ww+=2;
}
if(wait(0) == -1)
{
}
break;
}
return 0;
}
我要程序创建N children。 每个 child 都必须向 parent 发送一条消息。我使用 exec 任务是因为在我的任务中写到每个 child 都应该作为一个单独的程序运行。我创建了一个示例流,但它不起作用。
目前程序创建了 N childs 个进程。从 child 到 parent 的通信过程无效。
编辑:
对我来说发送和接收数据总是通过同样的事情。我发送进程的 PID,但总是选择相同的。
管道是解决此问题的极其不合适的工具,因为它们基本上是一对一的通信方法。您需要的是多对一的通信方式。为此,我建议使用 message queue。这将允许您的 parent 订阅消息队列并允许无限数量的 children 写入它,并且他们的消息全部被多路复用到 parent.
我无法了解您要对 double-fork 业务进行的操作。 我不想为你写完整的东西,但这里是我将如何编写代码的大纲:
int * pids;
int * fds;
int pipefds[2];
char * message = "message";
int alive = 0;
pids = malloc(n * sizeof(int *));
fds = malloc(n * sizeof(int *));
for (i = 0; i < n; ++i) {
if (pipe(pipefds) == -1) exit(1);
switch (pid = fork()) {
case -1: /* error */
exit(2);
case 0: /* child */
close(pipefds[0]);
write(pipefds[1], message, strlen(message)+1);
_exit(0);
default: /* parent */
closefds[1];
pids[i] = pid;
fds[i] = pipefds[0];
++alive;
}
}
while (alive > 0) {
/* select on the fds[] of all alive (fds[i] != -1) children */
/* if EINTR, do waitpid(-1, &status, WNOHANG); */
/* to see if a child has exited */
/* if so, find it in pids, say at index 'x', and: */
/* close(fds[x]); fds[x] = -1; --alive; */
/* if select said I/O ready for a pipe */
/* then read that pipe */
}