fork() em C
A chamada do sistema fork é usada para criar um novo processo, que é chamado de processo filho , que é executado simultaneamente com o processo que faz a chamada fork() (processo pai). Depois que um novo processo filho é criado, ambos os processos executarão a próxima instrução após a chamada de sistema fork(). Um processo filho usa o mesmo pc (contador de programa), os mesmos registros de CPU, os mesmos arquivos abertos que usam no processo pai.
Não leva parâmetros e retorna um valor inteiro. Abaixo estão os diferentes valores retornados por fork().
Valor negativo : a criação de um processo filho não foi bem-sucedida.
Zero : Retornado ao processo filho recém-criado.
Valor positivo : devolvido ao pai ou ao autor da chamada. O valor contém o ID do processo do processo filho recém-criado.
Observe que os programas acima não compilam no ambiente Windows.
- Prever a saída do seguinte programa: .
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main()
{
// make two process which run same
// program after this instruction
fork();
printf
(
"Hello world!\n"
);
return
0;
}
Saída:
Olá Mundo! Olá Mundo!
- Calcule o número de vezes que hello é impresso:
#include <stdio.h>
#include <sys/types.h>
int
main()
{
fork();
fork();
fork();
printf
(
"hello\n"
);
return
0;
}
Saída:
Olá Olá Olá Olá Olá Olá Olá Olá
O número de vezes que 'hello' é impresso é igual ao número de processos criados. Número total de processos = 2 n , onde n é o número de chamadas de sistema de bifurcação. Então aqui n = 3, 2 3 = 8
Vamos colocar alguns nomes de rótulos para as três linhas:
garfo(); // Linha 1 garfo(); // Linha 2 garfo(); // Linha 3 L1 // Haverá 1 processo filho / \ // criado pela linha 1. L2 L2 // Haverá 2 processos filho / \ / \ // criado pela linha 2 L3 L3 L3 L3 // Haverá 4 processos filho // criado pela linha 3
Portanto, há um total de oito processos (novos processos filho e um processo original).
Se quisermos representar a relação entre os processos como uma hierarquia em árvore, seria o seguinte:
O processo principal:
Processos P0 criados pela 1ª bifurcação: P1
Processos criados pela 2ª bifurcação: P2, P3
Processos criados pela 3ª bifurcação: P4, P5, P6, P7P0 / | \ P1 P4 P2 / \ \ P3 P6 P5 / P7
- Preveja o resultado do seguinte programa:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void
forkexample()
{
// child process because return value zero
if
(fork() == 0)
printf
(
"Hello from Child!\n"
);
// parent process because return value non-zero.
else
printf
(
"Hello from Parent!\n"
);
}
int
main()
{
forkexample();
return
0;
}
Saída:
1 Hello from Child! Olá do pai! (ou) 2 Olá do pai! Hello from Child!
No código acima, um processo filho é criado. fork() retorna 0 no processo filho e um inteiro positivo no processo pai.
Aqui, duas saídas são possíveis porque o processo pai e o processo filho estão sendo executados simultaneamente. Portanto, não sabemos se o sistema operacional primeiro dará controle ao processo pai ou ao processo filho.Importante: o processo pai e o processo filho estão executando o mesmo programa, mas isso não significa que sejam idênticos. O SO aloca dados e estados diferentes para esses dois processos, e o fluxo de controle desses processos pode ser diferente. Veja o próximo exemplo:
- Preveja o resultado do seguinte programa:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void
forkexample()
{
int
x = 1;
if
(fork() == 0)
printf
(
"Child has x = %d\n"
, ++x);
else
printf
(
"Parent has x = %d\n"
, --x);
}
int
main()
{
forkexample();
return
0;
}
Saída:
Pai tem x = 0 Criança tem x = 2 (ou) Criança tem x = 2 Pai tem x = 0
Aqui, a mudança da variável global em um processo não afeta dois outros processos porque os dados / estado de dois processos são diferentes. E também pai e filho são executados simultaneamente, de modo que duas saídas são possíveis.
fork() vs exec()
A chamada de sistema fork cria um novo processo. O novo processo criado por fork() é uma cópia do processo atual, exceto pelo valor retornado. A chamada de sistema exec() substitui o processo atual por um novo programa.
Exercício:
- Um processo executa o seguinte código:
for
(i = 0; i < n; i++)
fork();
O número total de processos filho criados é: (GATE-CS-2008)
(A) n
(B) 2 ^ n - 1
(C) 2 ^ n
(D) 2 ^ (n + 1) - 1;Veja esta solução.
- Considere o seguinte fragmento de código:
if
(fork() == 0) {
a = a + 5;
printf
(
"%d, %d\n"
, a, &a);
}
else
{
a = a –5;
printf
(
"%d, %d\n"
, a, &a);
}
Sejam u, v os valores impressos pelo processo pai e x, y os valores impressos pelo processo filho. Qual das opções a seguir é VERDADEIRA? (GATE-CS-2005)
(A) u = x + 10 ev = y
(B) u = x + 10 ev! = Y
(C) u + 10 = x e v = y
(D) u + 10 = x e v! = y
Veja isto para a solução. Preveja a saída do programa abaixo.
#include <stdio.h>
#include <unistd.h>
int
main()
{
fork();
fork() && fork() || fork();
fork();
printf
(
"forked\n"
);
return
0;
}
Veja isso para solução
Artigos relacionados:
Programa C para demonstrar processos fork() e pipe()
Zombie e Orphan em C
fork() e processos p / w de memória compartilhada criados com ele.
Referências:
http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html
Este artigo é uma contribuição de Team GeeksforGeeks e Kadam Patel . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando contribute.geeksforgeeks.org ou enviar o seu artigo para contribute@geeksforgeeks.org. Veja o seu artigo na página principal do GeeksforGeeks e ajude outros Geeks.
Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.
As postagens do blog Acervo Lima te ajudaram? Nos ajude a manter o blog no ar!
Faça uma doação para manter o blog funcionando.
70% das doações são no valor de R$ 5,00...
Diógenes Lima da Silva