Por que a fork() e wait() no pai?
-
11-12-2019 - |
Pergunta
Eu sei fork(), wait(), waitpid(), processos zombie...Eu compreendi lendo W.Richard Stevens, que é um livro muito bom.
Se nós não chamar wait() no pais a criança torna-se um zumbi após o término...o que é ruim!
Se nós chamada wait() pai-mãe, a espera para a criança terminar, recebe a terminação de status e, em seguida, continua.Escrever?
Eu tenho ido através de muitos exemplos de que a chamada fork() e wait() no pai.
Mas se em todos os pai vai esperar para a criança e para continuar depois que a criança termina, então não é real, multitarefa acontecendo(tecnicamente sim, existem 2 processos.Mas, logicamente, sem uso), então por que nós chamada fork() aqui?
Poderíamos ter escrito criança de código e, em seguida, mãe do código, em vez de fork() & wait (), como um único processo...não seria melhor?
Obrigado!
Solução
Às vezes, é útil garfo () mesmo que o pai seja imediatamente indo para bloquear.O caso mais comum é quando você está fazendo algo semelhante ao system () chamada, executando um comando externo e espera que ele conclua: você fará fork () + execve () .(Embora, no código moderno, você deve considerar usando posix_spawn () em vez disso para este propósito.)
No entanto, espera () não precisa bloquear.Você pode usar waitpid () com a bandeira wnohang para coletar o código de saída de qualquer processo concluído ou continuando imediatamente se ainda estiver em execução.
Outras dicas
O código que você escreve, entre fork()
e waitpid()
corre simultaniously, ao lado de criança garfo.
O pai aguarda até que a criança termina, muitas vezes, simplesmente para pegar dados entregues a partir criança e por este meio expor ao pai.Suponha que você executar um loop principal, onde as tarefas são executadas como 'fundo'.Por exemplo:
// 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;
}
}