我正试图解决这个问题,但我不能。
这是一个简短的描述:
我们有一个父有两个子进程(child_a,child_b)和N个字符串。
当前数据:data [i](0 ... N)
- Parent启动并等待来自child_b的信号。 Child_a正在等待。
- Child_b向父母发送信号并等待数据。
- 父将数据[i]写入管道并等待
- Child_b从pipe和printf()读取data [i]。然后等待Child_a
- Child_a生成一个随机数(1-5之间)并写入管道。
- Child_b从管道读取rand并发送给Parent。
- 父母将“data [i] - rand”写入文件。
- 从下一个数据开始......
醇>
这是我的代码:
FILE *fp2;
fp2 = fopen("bill.dat" , "a");
pid_t child_a, child_b;
int pipefd_a[2], pipefd_b[2];
char msg[100];
char sleep_time[10];
int stat;
signal(SIGUSR1, handler);
signal(SIGUSR2, handler);
if(pipe(pipefd_a) == -1 || pipe(pipefd_b) == -1){
perror("Error\n");
exit(EXIT_FAILURE);
}
int i;
for(i = 0; i < n; i++){
child_a = fork();
if(child_a < 0){
perror("Error\n");
}
if(child_a == 0){
sleep(1);
printf("Child_a-----\n");
srand(time(NULL));
int r = rand()%5+1;
char rand[2];
sprintf(rand, "%d", r);
printf("Child_a rand: %s\n", rand);
write(pipefd_b[1], rand, strlen(rand)+1);
printf("Child_a end-----\n");
exit(0);
}
else{
child_b = fork();
if(child_b == 0){
printf("Child_b sends a signal to parent\n");
kill(getppid(), SIGUSR1);
close(pipefd_a[1]);
read(pipefd_a[0], msg, sizeof(msg));
close(pipefd_a[0]);
printf("Child_b reads from pipe (from parent): %s\n", msg);
kill(child_a, SIGUSR2);
sleep(2);
read(pipefd_b[0], sleep_time, 10);
printf("Child_b reads from pipe (from child_a): %s\n", sleep_time);
fflush(NULL);
write(pipefd_b[1], sleep_time, sizeof(sleep_time));
close(pipefd_b[1]);
printf("Child_b end-----\n");
exit(0);
}
printf("============== %d ============== \n", i);
printf("Parent waiting for signal...\n");
pause();
printf("Signal received\n");
printf("Parent write into pipe\n");
close(pipefd_a[0]);
write(pipefd_a[1], data[i].address, 100);
kill(child_b, SIGUSR2);
waitpid(child_b, &stat, 0);
read(pipefd_b[0], msg, sizeof(msg));
fprintf(fp2, "%s - %s\n", data[i].address, msg);
printf("Parent writes into file: %s\n", msg);
}
}
fclose(fp2);
和我的输出(n = 2):
文件中总有2 ^ n行。 赋值需要两个子进程来实现这一点,我怀疑问题是循环中的“fork()”,但不明白我做错了什么。
答案 0 :(得分:1)
第一个问题是您将流程创建置于for循环中。 这就是你获得2n行的原因。如果你想读取一些数据表单文件N次,你就不能进行N次处理。
第二件事你需要3个管道来完成工作。管道是单向的,意味着一个进程只能写入管道而另一个进程只能读取它。一端用于写入,另一端用于读取,因此必须关闭未使用的描述符!
如果你能写完整个程序,我会更容易理解它并帮助你。 这是我试图做这项工作的骨架
int pipe_parent_to_childB[2], pipe_childB_to_parent[2], pipe_childA_to_childB;
if(pipe(pipe_parent_to_childB) == -1 || pipe(pipe_childB_to_parent) == -1 ||pipe(pipe_childA_to_childB) == -1)
{
perror("Error\n");
exit(EXIT_FAILURE);
}
//close read end because parent will write to pipe
close(pipe_parent_to_childB[0]);
switch(fork()) //create child b
{
case -1:
//error
case 0:
//now you are in child_b
close(pipe_parent_to_childB[1]);
close(pipe_childA_to_childB[1]);
//perform some action
default:
break;
}
}
switch(fork()) //crete child a
{
case -1:
//error
case 0:
//now you are in child_a
close(pipe_childA_to_childB[0]);
//perform some action
default:
break;
}
//here you are in parent process again. Send signals, wait for signals and write to pipe here
//from parent you send some data through pipe to process child_b N times
//after this you close write end of the pipe descriptor.