gpt4 book ai didi

c - 使用两个管道进行双向消息传递中的 SIGPIPE

转载 作者:行者123 更新时间:2023-11-30 14:59:53 32 4
gpt4 key购买 nike

嗨,我必须开发这个程序,创建 4 个 child ,并依次让他们做一个简单的操作。第一个进行求和,第二个进行余数,第三个进行乘法,第四个进行除法。父亲将在套接字上写入他希望 children “计算”的两个数字的字符串,每个 child 都应该读取这个字符串,提取数字并进行运算。显然,作为两个管道,父亲每次都需要写入字符串,因为 child 要读取。我真的不明白为什么在第二次迭代时,我收到了父亲写的 SIGPIPE。有人可以解释一下为什么吗?我调试了3天,但没有找到任何东西。非常感谢。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>

/*
fd_0 padre escribe y hijo lee ==== padre cierra fd_0[0] y hijo cierra fd_0[1]
fd_1 hijo escribe y padre lee === padre cierra fd_1[1] y hijo cierra fd_1[0]
*/


int main (int argc, char * argv[]){


char * str = malloc(100*sizeof(char));//hijo
char readbuffer_h[150];

char * stringa = malloc(100*sizeof(char));//padre
char readbuffer_p[150];


int a,b;
int x,y;
int n = 4;
int i,status,nbytes, pipe_status;
int pid, ppid,yo,padre;
int fd_0[2], fd_1[2] ;



pipe_status=pipe(fd_0);
if(pipe_status==- 1) {
perror("Error creando la tuberia 0\n");
exit(EXIT_FAILURE);
}


pipe_status=pipe(fd_1);
if(pipe_status== -1) {
perror("Error creando la tuberia 1 \n");
exit(EXIT_FAILURE);
}



for(i=0; i< n; i++){

if ((pid=fork()) <0 ){
printf("Error al emplear fork\n");
exit(EXIT_FAILURE);
}

/*-------------------------------------------------------------------------------------------------------------------------------------------------*/

else if (pid ==0){// soy el hijo


yo = getpid();
padre = getppid();
printf("HIJO: %d, mi padre es: %d\n", yo, padre);

close(fd_0[1]);
close(fd_1[0]);

//TODO


nbytes = read(fd_0[0], readbuffer_h, sizeof(readbuffer_h));

sscanf(readbuffer_h, "%d,%d", &x, &y);


switch(i) {

case 0 :
//TODO
sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. La suma es %d", yo,x,y,(x+y));
break;

case 1 :
//TODO
sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. La resta es %d", yo,x,y,(x-y));
break;

case 2 :
//TODO
sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. El producto es %d", yo,x,y,(x*y));
break;

case 3 :
//TODO
sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. El cociente es %d", yo,x,y,(x/y));
break;

}


write(fd_1[1], str, strlen(str));


exit(EXIT_SUCCESS);
}

/*-------------------------------------------------------------------------------------------------------------------------------------------------*/


else{ //soy el padre
yo = getpid();
printf("PADRE:%d\n", yo);

a = 3; b = 4;

close(fd_0[0]);
close(fd_1[1]);


sprintf(stringa,"%d,%d",a,b);
printf("Stringa padre : %s\n", stringa);
fflush(stdout);

write(fd_0[1],stringa,strlen(stringa)); // questa write non va a buon fine


wait(&status);

read(fd_1[0], readbuffer_p, sizeof(readbuffer_p));
printf("%s\n",readbuffer_p);
fflush(stdout);

}


}

close(fd_0[0]);
close(fd_0[1]);
close(fd_1[0]);
close(fd_1[1]);


return 0;
}

最佳答案

尝试使用相同的管道与每个 child 进行通信会给自己带来麻烦。

您在程序开始时创建了两个管道。在循环的第一次迭代中,父级 fork ,子级继承父级的所有打开文件描述符。子级关闭它不需要的管端,父级关闭它不需要的管端。沟通按预期进行(我想)——到目前为止一切都很好。

但现在考虑循环的第二次迭代。您再次 fork ,子级再次继承父级的打开文件描述符。但现在,子级想要使用的文件描述符已被父级在循环的上一次迭代中关闭。我有点惊讶的是,当 child 尝试使用这些文件描述符时,它会得到一个 EPIPE 而不是 EBADF,但我一点也不惊讶它读取尝试失败。

最干净的做法是为每个子级创建一对新的管道,而不是尝试重用一组管道。如果您想让它仅与一对一起工作,那么父进程必须避免关闭任何管道端(尽 pipe 进程可以关闭它们的副本,如果您愿意)。

关于c - 使用两个管道进行双向消息传递中的 SIGPIPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42448914/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com