Chamada do sistema Fork em C

Fork System Call C



A chamada de sistema fork () é usada para criar processos filhos em um programa C. fork () é usado onde o processamento paralelo é necessário em seu aplicativo. A função do sistema fork () é definida nos cabeçalhos sys / types.h e unistd.h . Em um programa em que você usa fork, você também precisa usar a chamada de sistema wait (). A chamada de sistema wait () é usada para esperar no processo pai até que o processo filho termine. Para finalizar um processo filho, a chamada de sistema exit () é usada no processo filho. A função wait () é definida no cabeçalho sys / wait.h e a função exit () é definida no cabeçalho stdlib.h .

Fig 1: fluxo de trabalho fork () básico

Fig 1: fluxo de trabalho fork () básico







Neste artigo, vou mostrar como usar a chamada de sistema fork () para criar processos filho em C. Então, vamos começar.



fork () Sintaxe e valor de retorno:

A sintaxe da função do sistema fork () é a seguinte:



pid_t fork(vazio);

A função de sistema fork () não aceita nenhum argumento. Ele retorna um inteiro do tipo pid_t .





Em caso de sucesso, fork () retorna o PID do processo filho que é maior que 0. Dentro do processo filho, o valor de retorno é 0. Se fork () falhar, então ele retornará -1.

Bifurcação simples () Exemplo:

Um exemplo simples fork () é fornecido abaixo:



#incluir
#incluir
#incluir
#incluir
#incluir

inta Principal(vazio) {
pid_t pid=garfo();

E se(pid== 0) {
printf ('Criança => PPID:% d PID:% d n',getppid(),getpid());
saída (EXIT_SUCCESS);
}
outro E se(pid> 0) {
printf ('Pai => PID:% d n',getpid());
printf ('Esperando que o processo filho termine. n');
esperar(NULO);
printf ('Processo filho concluído. n');
}
outro {
printf ('Incapaz de criar processo filho. n');
}

RetornaEXIT_SUCCESS;
}

Aqui, usei fork () para criar um processo filho a partir do processo principal / pai. Em seguida, imprimi o PID (ID do processo) e o PPID (ID do processo pai) dos processos filho e pai. No processo pai, a espera (NULL) é usada para aguardar a conclusão do processo filho. No processo filho, exit () é usado para finalizar o processo filho. Como você pode ver, o PID do processo pai é o PPID do processo filho. Então, o processo filho 24738 pertence ao processo pai 24731 .

Você também pode usar funções para tornar seu programa mais modular. Aqui eu usei processTask () e parentTask () funções para os processos filho e pai, respectivamente. É assim que fork () é realmente usado.

#incluir
#incluir
#incluir
#incluir
#incluir

vaziochildTask() {
printf ('Olá Mundo n');
}

vazioparentTask() {
printf ('Tarefa principal. n');
}

inta Principal(vazio) {
pid_t pid=garfo();

E se(pid== 0) {
childTask();
saída (EXIT_SUCCESS);
}
outro E se(pid> 0) {
esperar(NULO);
parentTask();
}
outro {
printf ('Incapaz de criar processo filho.');
}

RetornaEXIT_SUCCESS;
}

O resultado do programa acima:

Executando vários processos filho usando fork () e Loop:

Você também pode usar o loop para criar quantos processos filho forem necessários. No exemplo abaixo, criei 5 processos filho usando o loop for. Também imprimi o PID e o PPID dos processos filhos.

#incluir
#incluir
#incluir
#incluir
#incluir

inta Principal(vazio) {
para(inteu= 1;eu<= 5;eu++) {
pid_t pid=garfo();

E se(pid== 0) {
printf ('Processo filho => PPID =% d, PID =% d n',getppid(),getpid());
saída (0);
}
outro {
printf ('Processo pai => PID =% d n',getpid());
printf ('Esperando que os processos filho terminem ... n');
esperar(NULO);
printf ('processo filho concluído. n');
}
}

RetornaEXIT_SUCCESS;
}

Como você pode ver, o ID do processo pai é o mesmo em todos os processos filho. Portanto, todos eles pertencem ao mesmo pai. Eles também são executados de forma linear. Um após o outro. Controlar processos filhos é uma tarefa sofisticada. Se você aprender mais sobre a programação do sistema Linux e como ela funciona, poderá controlar o fluxo desses processos da maneira que desejar.

Exemplo da vida real:

Diferentes cálculos matemáticos complexos, como md5, sha256, etc., a geração de hash requer muito poder de processamento. Em vez de computar coisas assim no mesmo processo do programa principal, você pode simplesmente calcular o hash em um processo filho e retornar o hash ao processo principal.

No exemplo a seguir, eu gerei um código PIN de 4 dígitos em um processo filho e o enviei para o processo pai, o programa principal. Então, imprimi o código PIN a partir daí.

#incluir
#incluir
#incluir
#incluir
#incluir

intgetPIN() {
// use PPID e PID como semente
srand (getpid() +getppid());
intsegredo= 1000 + fileira () % 9000;
Retornasegredo;
}

inta Principal(vazio) {
intfd[2];
tubo(fd);
pid_t pid=garfo();

E se(pid> 0) {
fechar(0);
fechar(fd[1]);
depois de(fd[0]);

intnúmero secreto;
size_treadBytes=leitura(fd[0], Enúmero secreto, tamanho de(número secreto));

printf ('Aguardando PIN ... n');
esperar(NULO);
printf ('Bytes lidos:% ld n',readBytes);
printf ('PIN:% d n',número secreto);
}
outro E se(pid== 0) {
fechar(1);
fechar(fd[0]);
depois de(fd[1]);

intsegredo=getPIN();
escrever(fd[1], Esegredo, tamanho de(segredo));
saída (EXIT_SUCCESS);
}

RetornaEXIT_SUCCESS;
}

Como você pode ver, cada vez que executo o programa, recebo um código PIN de 4 dígitos diferente.

Então, é basicamente assim que você usa a chamada de sistema fork () no Linux. Obrigado por ler este artigo.