Aspettando il processo infantile per terminare, o no - c
-
20-12-2019 - |
Domanda
Sto cercando di fare un incarico per una delle mie classi e nessun professori / compagni di classe sono tornati da me. Quindi, prima di rispondere, per favore non darmi alcuna risposta esatta! Solo spiegazioni!
Cosa devo fare è scrivere il programma AC (timeout.c) che assume due argomenti della riga di comando, w e t, dove w è la quantità di tempo in secondi il processo figlio dovrebbe prendere prima di uscire, e t è il Importo del tempo Il processo principale dovrebbe attendere il processo figlio, prima di uccidere il processo figlio e la stampa di un messaggio "Time Out". Fondamentalmente, se w> t, dovrebbe esserci un timeout. Altrimenti, il bambino dovrebbe terminare il suo lavoro e non viene stampato alcun messaggio Timeout.
Quello che volevo fare è stato solo il sonno del processo genitore per i secondi, quindi uccidere il processo figlio e stampare il timeout, tuttavia la stampa del messaggio di timeout non avverrà in entrambi i casi. Come posso controllare che il processo figlio sia terminato? Mi è stato detto di usare Alarm () per questo, tuttavia non ho idea di cosa utilizzerebbe quella funzione servire.
Ecco il mio codice nel caso qualcuno vuole dare un'occhiata:
void handler (int sig) {
return;
}
int main(int argc, char* argv[]){
if (argc != 3) {
printf ("Please enter values W and T, where W\n");
printf ("is the number of seconds the child\n");
printf ("should do work for, and T is the number\n");
printf ("of seconds the parent process should wait.\n");
printf ("-------------------------------------------\n");
printf ("./executable <W> <T>\n");
}
pid_t pid;
unsigned int work_seconds = (unsigned int) atoi(argv[1]);
unsigned int wait_seconds = (unsigned int) atoi(argv[2]);
if ((pid = fork()) == 0) {
/* child code */
sleep(work_seconds);
printf("Child done.\n");
exit(0);
}
sleep(wait_seconds);
kill(pid, SIGKILL);
printf("Time out.");
exit(0);
}
. Soluzione
Sebbene Waitpid ti porterebbe lo stato di ritorno del bambino, il suo utilizzo predefinito costringerebbe il genitore ad attendere fino a quando il bambino termina.
Ma il tuo requisito (se ho capito correttamente) Vuole solo il genitore di attendere un certo tempo, allarme () può essere utilizzato per farlo.
Quindi, è necessario utilizzare WaitPid () con un'opzione specifica che restituisce immediatamente se il bambino non è ancora uscito (studia i parametri dell'API).Quindi se il bambino non usciva, potresti ucciderlo, altrimenti ricevi già il suo stato di ritorno.
Altri suggerimenti
Volete che il programma timeout
si fermi più o meno non appena il comando finisce, quindi se si dice timeout -t 1000 sleep 1
il programma di protezione si arresta dopo circa 1 secondo, non dopo 1000 secondi.
Il modo per farlo è quello di impostare un allarme di qualche tipo - classicamente, con la chiamata di sistema alarm()
e un gestore di segnale per SIGALRM
- e quindi disporre del processo principale eseguire wait()
o waitpid()
in modo che quando il bambino muore, si svegliasu e raccoglie il cadavere.Se il processo genitore ottiene il segnale di allarme, può stampare il suo messaggio e inviare minacce di morte di qualche tipo a suo figlio.Potrebbe essere ragionevole provare il sigterm e / o sospettare prima di ricorrere a Sigkill;I segnali SIGTERM e SighPup danno al bambino errante la possibilità di ripulire mentre Sigkill no.
Se sai come gestire i segnali, potresti prendere SIGALRM e SIGChld nel tuo processo genitore.SIGCHLD verrà sollevato quando il client termina e SIGALRM quando scade il timer.Se il primo segnale rialzato è SIGALRM, il timeout è scaduto, altrimenti, se il primo segnale che il genitore cattura è SIGCHLD, il bambino si è fermato prima della scadenza del timeout.
aspettare () o waitpid () sarebbe ancora necessario raccogliere il bambino terminato.