我的程序会创建与用户放入参数一样多的子项。将消息发送给父母时遇到问题。我希望每个孩子都使用烟斗向父母发送信息。我不知道怎么做。我知道它对一个孩子有用: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个孩子。 每个孩子都必须向父母发送消息。我使用了exec任务,因为在我的任务中写道,每个孩子都应该作为一个单独的程序运行。我创建了一个示例流,但它无法正常工作。
现在程序创建了N个子进程。从孩子的父母过程的沟通不工作。
编辑:
对我来说,发送和接收数据始终是通过相同的事情。我发送过程的PID,但总是选择相同的。
答案 0 :(得分:1)
管道是一个非常不适合这个问题的工具,因为它们基本上是一对一的通信方法。您需要的是多对一的通信方法。为此,我建议使用message queue。这将允许您的父级订阅消息队列,并允许无限数量的子节点写入消息队列,并将其消息全部复制到父节点。
答案 1 :(得分:1)
我不能按照你想要的双叉业务来做。 而且我不倾向于为你写整篇文章,但这里是我如何编写代码的概述:
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 */
}