Perché fork () e quindi aspettare () nel genitore?
-
11-12-2019 - |
Domanda
Conosco forchetta (), attesa (), waitpid (), processi zombie ... Li ho capiti leggendo W. Richard Stevens che è un ottimo libro.
Se non chiamiamo l'attesa () nel genitore, il bambino diventa uno zombie dopo la risoluzione ... che è cattivo!
Se chiamiamo wait () nel genitore, il genitore attende che il bambino chiresse, riceve lo stato di terminazione e poi continua. Scrivi?
Ho attraversato molti esempi che chiamano forchetta () una volta e quindi aspettare () nel genitore.
Ma se a tutti i genitori attenderà per il bambino e continuerà dopo che il bambino termina, allora non c'è il multitasking attuale in corso (tecnicamente sì ci sono 2 processi. Ma logicamente senza uso) allora perché chiamiamo forchetta () qui?
Avremmo potuto scrivere il codice del bambino e poi il codice del genitore invece di forchetta () e attendere () come un singolo processo ... non sarebbe meglio?
Grazie!
Soluzione
A volte, è utile Fork () anche se il genitore sta per bloccare immediatamente.Il caso più comune è quando stai facendo qualcosa di simile al sistema System () chiama, eseguendo un comando esterno e aspettandolo per completare: lo farai Fork () + Esegui () .(Anche se, nel codice moderno, dovresti prendere in considerazione l'utilizzo di Posix_Spawn () invece per questo scopo.)
Tuttavia, Attendi () non è necessario bloccare.È possibile utilizzare WaitPid () con flag Wnohang per raccogliere il codice di uscita di qualsiasi processo completato o proseguire immediatamente se è ancora in esecuzione.
Altri suggerimenti
Il codice che scrivi ingetween fork()
e waitpid()
esegue simultaneamente, accanto alla forchetta figlio.
Il genitore attende fino a quando il bambino finisce, spesso semplicemente per raccogliere i dati consegnati dal bambino e la con la presente espongono al genitore. Supponiamo di eseguire un ciclo principale in cui le attività vengono eseguite come "sfondo".Ad esempio:
// a simple scheduler
while(1) {
if(done_task_1) {
// if done_task_1 is ever to change in the parent memory scope,
// parent must know the exit status of its child fork.
// otherwise there is no way to enter this if sentance, ever
collect_data_1();
run_task_1 = 0;
}
else if(run_task_1 == 1) {
// iterate instructions for a sec
posix_kill(pid_task_1, SIGCONT);
sleep(1);
posix_kill(pid_task_1, SIGSTOP);
}
if(done_task_2) {
collect_data_2();
run_task_2 = 0;
}
else if(run_task_2 == 1) {
// iterate instructions for a sec
posix_kill(pid_task_2, SIGCONT);
sleep(1);
posix_kill(pid_task_2, SIGSTOP);
}
if(run_task_1 == 0 && run_task_2 == 0) {
break;
}
}
.