Come utilizzare dup2/chiudere correttamente per collegare questi tre processi?
Domanda
Sto cercando di connettere correttamente tre processi per consentire la comunicazione tra process tra di loro. Ho un processo, scanner, che prende la stdin del genitore e quindi elabora le parole all'interno del flusso. Se una lunghezza della parola è strana, la invia a un processo, se è uniforme, lo invia a un altro. Questi processi dovrebbero assorbire queste parole tramite stdin (presumo) e quindi consegnare alcune informazioni al processo scanner tramite stdout. Lo stdout di pari/dispari dovrebbe essere reindirizzato allo scanner, che quindi leggerà (usando leggi) e quindi elabora/elabora le parole. È un esercizio accademico, non pratico. Ecco come sarebbe una foto:
Ecco come appare al momento il mio codice. Il problema è che non sono esattamente sicuro di cosa dup e cosa chiudere. Una volta capito che dovrei essere a posto! Tutto il consiglio sarebbe apprezzato.
Descrittori di file:
int scannertoeven[2]; int scannertoodd[2];
int eventoscanner[2]; int oddtoscanner[2];
//Pipe stuff here (ommitted)
Codice:
//Create the child processes
if ((scanner_pid = fork()) == 0) {
//We need the scanner pid so even and odd can send signals to it
char pidofparent[sizeof(getpid())];
sprintf(pidofparent, "%i", getpid());
//Even stuff
if ((even_pid = fork()) == 0) {
close(scannertoodd[0]); close(scannertoodd[1]);
close(oddtoscanner[0]); close(oddtoscanner[1]);
//Not sure which ones to close
close(scannertoeven[0]); close(scannertoeven[1]);
close(eventoscanner[0]); close(eventoscanner[1]);
//Correct?
close(STDIN_FILENO);
dup2(scannertoeven[0], STDIN_FILENO);
close(STDOUT_FILENO);
dup2(eventoscanner[1], STDOUT_FILENO);
if(execl("./evenodd", "even", pidofparent, NULL ) == -1) {
printf("execl Error!");
exit(1);
}
//Odd Stuff
} else if ((odd_pid = fork()) == 0){
close(scannertoeven[0]); close(scannertoeven[1]);
close(eventoscanner[0]); close(eventoscanner[1]);
//Not sure which ones to close
close(scannertoodd[0]); close(scannertoodd[1]);
close(oddtoscanner[0]); close(oddtoscanner[1]);
//Correct?
close(STDIN_FILENO);
dup2(scannertoodd[0], STDIN_FILENO);
close(STDOUT_FILENO);
dup2(oddtoscanner[1], STDOUT_FILENO);
if(execl("./evenodd", "odd", pidofparent, NULL ) == -1) {
printf("execl Error!");
exit(1);
}
//Actual Scanner
} else {
// Not sure which ones to close- this is very wrong
close(scannertoeven[0]); close(scannertoeven[1]);
close(eventoscanner[0]); close(eventoscanner[1]);
close(scannertoodd[0]); close(scannertoodd[1]);
close(oddtoscanner[0]); close(oddtoscanner[1]);
//Not sure what to dup either
dup2(scannertoodd[1], STDOUT_FILENO);
dup2(scannertoeven[1], STDOUT_FILENO);
if(execl("./scanner", "scanner", stoeven, stoodd, eventos, oddtos, NULL ) == -1) {
printf("execl Error!");
exit(1);
}
//Wait twice here, or three times in main?
waitpid(odd_pid, &status2, 0);
waitpid(even_pid, &status3, 0);
}
//Main
} else {
//Close Pipes
close(scannertoodd[0]); close(scannertoeven[0]); close(eventoscanner[0]); close(oddtoscanner[0]);
close(scannertoodd[1]); close(scannertoeven[1]); close(eventoscanner[1]); close(oddtoscanner[1]);
//Wait for children to finish
waitpid(scanner_pid, &status1, 0);
printf("Done\n");
}
Soluzione
Non sono sicuro della logica. Ma il modo in cui usi DUP2 non è giusto.
Il seguente codice nel processo "anche":
close(STDIN_FILENO);
dup2(scannertoeven[0], STDIN_FILENO);
close(STDOUT_FILENO);
dup2(eventoscanner[1], STDOUT_FILENO);
dovrebbe essere:
dup2(scannertoeven[0], STDIN_FILENO);
// You should close scannertoeven[0], not STDIN. After this dup2, the even
// process will receive input from scannertoeven[0]
close(scannertoeven[0]);
// Note the the scannertoeven[0] is not "really" closed, just that the file
// is "attached" to STDIN
dup2(eventoscanner[1], STDOUT_FILENO);
// Same as above. After this dup2, all the even process's output will go
// to eventoscanner[1]
close(eventoscanner[1]);
Lo stesso del processo "dispari".
Qui è Un esempio di DUP2, per tua referenza.