gpt4 book ai didi

c - 异步将值返回给父进程

转载 作者:行者123 更新时间:2023-11-30 17:06:55 25 4
gpt4 key购买 nike

我参与了使用 fork 的练习的解决。语句是这样的:1 个父级创建 3 个子级,它们具有随机且不同的执行时间,并且必须将各自的值返回给父级。所以,到目前为止,我能够创建和执行子进程并捕获它们的一些值,但此后执行变得疯狂。到目前为止我得到的代码是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAXCAPOS 3
#define MAXCOMERCIOS 3

/* Funcion que calcula aleatorios */
int calculaAleatorios(int min, int max) {
return rand() % (max-min+1) + min;
}

/* Funcion para dar más tiempo a que los negocios paguen */
void darPlazo() {
printf("\nDON: ¡Chicos! Decidle a los comerciantes que me deben dinero, que como no paguen lo que me deben, la semana que viene quemare sus tiendas.");
}

/* Funcion para dar una leccion a los negocios */
void darLeccion() {
printf("\nDON: ¡Chicos! Quemad los comercios que no han pagado esta semana.");
}

/* Funcion para generar un consejo */
void generaConsejo() {
sleep(10);
if(calculaAleatorios(0,1)==0) {
printf("\nConsigliere: Ya he deliberado SIGUSR1");
kill(getppid(), SIGUSR1);
} else {
printf("\nConsigliere: Ya he deliberado SIGUSR2");
kill(getppid(), SIGUSR2);
}
}

int main(void){
pid_t pidDon;
pid_t pidCapo[MAXCAPOS];
pid_t pidConsigliere;
int i = 1, j = 1;
int totalImpagos = 0;
for (i; i <= MAXCAPOS; i++){
/* Forkeando pidDon para obtener los capos */
switch (pidDon = fork()){
case -1:
perror("Error en la llamada a la funcion fork()");
exit(EXIT_FAILURE);
break;
case 0:
{
int noPagan = 0, tiempo = 0;
pidCapo[i] = getpid();
srand(pidCapo[i]); /*Generamos una semilla por el pid, dentro del proceso hijo para obtener semillas diferentes*/
printf("\nDON: Contrato al capo%d (pid: %d)", i, pidCapo[i]);
/* VISITAR LOS COMERCIOS Y RECIBIR CUANTOS HAN PAGADO (int) */
for (j; j <= MAXCOMERCIOS; j++){
tiempo = calculaAleatorios(5, 10); /* Genera un tiempo aleatorio entre 5 y 10 */
printf("\n Capo%d: %d Segundos para despertar (pid: %d)", i, tiempo, pidCapo[i]);
sleep(tiempo);
printf("\n Capo%d: Visita el comercio %d (pid: %d)", i, j, pidCapo[i]);
if (calculaAleatorios(0, 1) == 0){
printf("\n Capo%d: El comercio %d no me ha pagado, malditas ratas!! (pid: %d)", i, j, pidCapo[i]);
noPagan++;
} else {
printf("\n Capo%d: El comercio %d ha pagado (pid:%d)", i, j, pidCapo[i]);
}
}
printf("\nCapo%d: tengo %d morosos", i, noPagan);
exit(noPagan);
break;
}
default:
break;
}
}
/*Proceso DON*/
// Crear señales
printf("\nDON: Voy a esperar noticias de mis capos... (pid: %d)", getpid());
signal(SIGUSR1, darPlazo); // Unimos la señal SIGUSR1 a su procedimiento
signal(SIGUSR2, darLeccion); //Unimos la señal SIGUSR2 a su procedimiento
if (pidDon != 0 && pidDon != -1){
for (i = 1; i <= MAXCAPOS; i++){
int retorno;
waitpid(pidCapo[i], &retorno, 0);
retorno = WEXITSTATUS(retorno);
printf("\nDON: Al capo %d no le han pagado %d comercios", i, retorno);
totalImpagos += retorno;
}
sleep(30);
if (totalImpagos == 0){
printf("\nDON: Que bien, esta vez han pagado todos :D");
printf("\nDON: He terminado mi dia\n");
return (0);
} else {
if (totalImpagos == 1){
printf("\nDON: No me ha pagado 1 comercio, grrrrrrrr!!!!");
}
if (totalImpagos > 1){
printf("\nDON: No me han pagado %d comercios, estoy muy encabronado!", totalImpagos);
}
printf("\nDON: Consultare con mi consigliere");
/*Proceso Consigliere*/
pidConsigliere = fork();
if (pidConsigliere == -1){
perror("\nFallo al crear el proceso Consigliere");
exit(EXIT_FAILURE);
}
else if (pidConsigliere == 0){
signal(SIGUSR1, generaConsejo); // Unimos la señal SIGUSR1 a su procedimiento
printf("\nConsigliere: Hola Don! Espero tu señal");
pause();
exit(0);
}
/*Vuelta al DON*/
// Consulta al consigliere
sleep(5);
printf("\DON: Le mando una señal a mi consigliere");
if (kill(pidConsigliere, SIGUSR1) == -1){ // Lanzamos kill contra pidConsigliere y evaluamos el error
perror("\nFallo al enviar la señal al Consigliere");
exit(EXIT_FAILURE);
}
printf("\nDON: Esperare mientras mi consigliere delibera");
pause();
}
}
printf("\nDON: He terminado mi dia\n");
return (0);
}

所以,我需要知道如何正确检索所有 3 个返回值。提前致谢。

最佳答案

如何在父级中安装 SIGCHLD 信号处理程序,并在调用它时,使用 wait()waitpid() 获取子级的退出状态wait4()

这是规范的做法。我不太确定 SIGUSR1/2 的目的是什么。

关于c - 异步将值返回给父进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34354638/

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