这里我有一个程序,其中父进程创建了几个子进程,传递 每个都有一个独特的整数。然后每个子进程将读取的整数写回到父进程,该进程将结果打印到标准输出:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#define R 0
#define W 1
void run_child(int in, int out){
int r;
int it;
while((r = read(in, &it, sizeof(it))) != 0){
if(r == -1){
perror("read");
exit(1);
}
//word[r] = '\0';
int w = write(out, &it, sizeof(it));
if(w == -1){
perror("write");
exit(1);
}
if(close(out) == -1){
perror("close");
exit(1);
}
}
}
int main(int argc, char **argv) {
// Process fan
int i;
int n;
int num_kids;
int from_parent[2];
int to_parent[2];
if(argc != 2) {
fprintf(stderr, "Usage: fan_write <numkids>\n");
exit(1);
}
num_kids = atoi(argv[1]);
int status;
char word[32];
for(i = 0; i < num_kids; i++) {
if(pipe(from_parent) == -1){
perror("pipe");
exit(1);
}
if(pipe(to_parent) == -1){
perror("pipe");
exit(1);
}
int g = i;
write(from_parent[W], &g, sizeof(int));
n = fork();
if(n < 0) {
perror("fork");
exit(1);
}
if(n == 0){
if(close(from_parent[W]) == -1){
perror("close");
exit(1);
}
if(close(to_parent[R]) == -1){
perror("close");
exit(1);
}
dup2(from_parent[R], STDIN_FILENO);
if(close(from_parent[R]) == -1){
perror("close");
exit(1);
}
run_child(STDIN_FILENO, to_parent[W]);
close(to_parent[W]);
exit(0);
}
if(close(from_parent[R]) == -1){
perror("close");
exit(1);
}
if(close(to_parent[W]) == -1){
perror("close");
exit(1);
}
if(close(from_parent[W]) == -1){
perror("close");
exit(1);
}
for(i=0;i<num_kids;i++){
int read_int;
int r = read(to_parent[R], &read_int, sizeof(int));
printf("read %d bytes\n", r);
if(r == -1){
perror("read");
exit(1);
}
printf("%d\n", read_int);
}
}
for(i = 0; i < num_kids; i++){
wait(&status);
}
return 0;
}
使用num_kids = 4,我希望程序每次读取4个字节并打印出来 不同的整数。但是,运行时,它在一次迭代中读取4个字节,然后读取 在以下迭代中为0个字节,并反复打印相同的整数。我不确定如何解决它。
编辑:解决了!提示:对管道使用文件描述符矩阵。
答案 0 :(得分:2)
你有错误的概念来读取循环中所有num_kids
子进程中的数字,你每次都是从单个孩子和每个孩子中读取循环:
for(i=0;i<num_kids;i++){
int read_int;
int r = read(to_parent[R], &read_int, sizeof(int));
printf("read %d bytes\n", r);
if(r == -1){
perror("read");
exit(1);
}
printf("%d\n", read_int);
}
代码是否也为包括父项在内的每个子项运行,因为您无条件地在子/父进程中运行此循环。但是父母可以从单个孩子那里读到你第一次获得4个字节然后0
的原因。因为孩子回来了一次。从您的代码中删除上面的for循环,并像我在下面建议的那样:
你应该这样做(阅读评论):
if(n == 0){
//child
}
else{
// read in parent without loop
}
正确的方法是:
if(n == 0){//child
if(close(from_parent[W]) == -1){
perror("close");
exit(1);
}
if(close(to_parent[R]) == -1){
perror("close");
exit(1);
}
dup2(from_parent[R], STDIN_FILENO);
if(close(from_parent[R]) == -1){
perror("close");
exit(1);
}
run_child(STDIN_FILENO, to_parent[W]);
close(to_parent[W]);
exit(0);
}
else{ // parent
write(from_parent[W], &g, sizeof(int));
int read_int;
int r = read(to_parent[R], &read_int, sizeof(int));
printf("read %d bytes\n", r);
if(r == -1){
perror("read");
exit(1);
}
printf("%d\n", read_int);
}
它的工作方式如下:
:~$ ./a.out 4
read 4 bytes
0
read 4 bytes
1
read 4 bytes
2
read 4 bytes
3
答案 1 :(得分:1)
if (n == 0) { //child
if(close(from_parent[W]) == -1) {
perror("close");
exit(1);
}
if(close(to_parent[R]) == -1) {
perror("close");
exit(1);
}
run_child(from_parent[R], to_parent[W]);
close(from_parent[R]); // ignore checking return code here!
close(to_parent[W]); // ignore checking return code here!
exit(0);
}
// And this is what run_child looks like
void run_child(int in, int out){
int r;
int it;
while((r = read(in, &it, sizeof(it))) != 0){
if(r == -1){
perror("read");
exit(1);
}
int w = write(out, &it, sizeof(it));
if(w == -1){
perror("write");
exit(1);
}
}
}
答案 2 :(得分:0)
我把答案代码混淆了,这是最后的结果.. 一切顺利
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#define R 0
#define W 1
void run_child(int in, int out){
int r;
int it;
while((r = read(in, &it, sizeof(it))) != 0){
if(r == -1){
perror("read");
exit(1);
}
int w = write(out, &it, sizeof(it));
//perror("write:");
//close(out) ;
exit(1);
}
}
int main(int argc, char **argv) {
// Process fan
int i;
int n;
int num_kids;
int from_parent[2];
int to_parent[2];
if(argc != 2) {
fprintf(stderr, "Usage: fan_write <numkids>\n");
exit(1);
}
num_kids = atoi(argv[1]);
int status;
char word[32];
for(i = 0; i < num_kids; i++) {
if(pipe(from_parent) == -1){
perror("pipe");
exit(1);
}
if(pipe(to_parent) == -1){
perror("pipe");
exit(1);
}
int g = i;
write(from_parent[W], &g, sizeof(int));
n = fork();
if(n < 0) {
perror("fork");
exit(1);
}
if(n == 0){//child
if(close(from_parent[W]) == -1){
perror("close");
exit(1);
}
if(close(to_parent[R]) == -1){
perror("close");
exit(1);
}
run_child(from_parent[R], to_parent[W]);
if(close(from_parent[R]) == -1){
perror("close");
exit(1);
}
if(close(to_parent[W]) == -1){
perror("close");
exit(1);
}
exit(0);
}
else{ // parent
write(from_parent[W], &g, sizeof(int));
int read_int;
int r = read(to_parent[R], &read_int, sizeof(int));
printf("read %d bytes\n", r);
if(r == -1){
perror("read");
exit(1);
}
printf("%d\n", read_int);
}
}
for(i = 0; i < num_kids; i++){
wait(&status);
}
return 0;
}