fork, exec, e daemon

Terceiro artigo da série Comunicação entre processos, nesse artigo é apresentado o funcionamento do fork, exec e do daemon

Introdução

O artigo anterior descreveu a biblioteca hardware que é necessária para viabilizar o desenvolvimento dos exemplos, com o desenvolvimento da camada abstração concluída e instalada, e as pendências resolvidas, ainda necessitamos de alguns conceitos para prosseguir que são a combinação de fork e exec, e a definição do que é um daemon, que serão de vital importância para os próximos artigos, que seguirão esse modelo.

fork()

O fork() é um system call capaz de criar um novo processo denominado filho, que é uma cópia exata do processo original denominado pai. Para utilizar o fork() é necessário incluir os seguintes includes:

Para exemplificar vamos criar uma aplicação muito conhecido por todos, o famoso hello world, a seguir vemos o seguinte código fonte que tem a finalidade de mostrar no console a string hello world:

O output desse código será:

O resultado do código anterior resultou em uma grande confusão agora é necessário explicar o que ocorre por de trás das cortinas.

  • Pessoa : Duas strings hello world?
  • Alguém : Isso mesmo, uma mensagem do processo original e outro do processo clone.
  • Pessoa : Mas como é possível haver um clone?
  • Alguém : Não acredita? Tudo bem então vamos provar.
  • Pessoa : Mas como fazer isso?
  • Alguém : Bom para isso precisamos encontrar evidências sobre esse mistério.
  • Pessoa : Como pode apresentar duas mensagens sendo que o programa é um só? E somente existe uma ocorrência de printf. Bizarro.
  • Alguém : Não nos resta alternativa, precisamos interrogar, vamos perguntar para o programa quem é ele com a função getpid.

Ao executar é possível ver a saída com o resultado:

Oh não, isso deve ser um pesadelo é o ataque dos clones. Hey vai com calma não é isso que você está pensando, isso é só um Jutsu Clone das sombras, é uma técnica para poder dividir o trabalho. Bom isso seria útil para realizar as tarefas de casa. A figura abaixo demonstra o que ocorre durante o fork:

68747470733a2f2f696e6472616468616e7573682e6769746875622e696f2f696d616765732f7368656c6c2d706172742d322f6578656376702e6a7067

Como apresentado na figura é possível notar que o fluxo é ramificado após a execução do fork, para verificar quem é quem, com o retorno do fork é possível distiguir qual processo é qual. Vejamos mais um exemplo para demonstrar o resultado do fork:

A saída fica assim :

Como pode ser observado o clone retorna o valor 0, o original recebe o PID do clone, e se houver erro o retorno é -1.

Mas para que serve isso? Para o nosso propósito precisamos apresentar mais um componente.

exec()

  • Clone : Cara não acredito?
  • Alguém : O que foi que aconteceu?
  • Clone: Eu não passo de um mero clone.
  • Alguém: Não cara, não diga isso você pode ser um clone mas você pode seguir o seu próprio caminho, ser o que quiser ser.
  • Clone: Sério?
  • Alguém: Sim você precisa somente de um contexto, e assim seguir o seu próprio caminho.
  • Clone: Nossa isso seria ótimo mas como eu faço isso?
  • Alguém: Temos um recurso bastante versátil conhecido como exec, com ele é possível carregar um outro programa, que trocará todo o contexto anterior, e você será promovido, dessa forma você pode ser que você quiser.

O exec é um system call capaz de carregar outro programa, trocando todo o contexto do programa que o invoca. O exec possui várias formas de ser utilizado e suas variações se devem ao passar do tempo programadores o adaptavam conforme suas necessidades resultando nessa quantidade de funções, para melhor atendê-lo verifique o man pages para maiores informações sobre o exec:

Para exemplificar vamos criar uma outra aplicação

O programa a seguir é o responsável pela criação do clone. após clonado o programa clone decide que quer se tornar um contador e seguir carreira nessa área.

O programa a seguir apresenta em um novo momento, talvez um momento de realização para o clone, que mesmo sendo um clone pode decidir qual caminho trilhar, e decidiu virar um contador, muito bom meu caro amigo persiga o seu sonho.

daemon()

  • Alguém: Agora como tudo foi esclarecido vamos ver o que é o daemon.
  • Pessoa: Demon? Que isso cara?
  • Alguém: Não Demon, mas sim daemon, que coisa não?

Basicamente daemon é uma instância que roda em segundo plano, sem a interação de STDIN, STDOUT e STDERR. Normalmente fornece algum tipo de serviço como por exemplo o sshd(security shell daemon) que ouve conexões usando protocolo ssh e atua como servidor para o protocolo, possui um ciclo de vida desde o power on da máquina até o shutdown(caso não haja segfault ;P). No tópico de fork, é gerado uma cópia do programa corrente, esse programa filho é uma espécie de daemon, pois roda em segundo plano após o fork. Para a criação de um daemon existe um roteiro onde alguns passos devem ser seguidos, e existe também uma system call que abstrai todo o processo de criação:

Criação pelo modelo tradicional

  • Gerar o clone do processo através do fork para que o processo rode em background
  • Alterar as permissões de acesso, para esse caso o argumento 0 significa que as permissões serão herdadas
  • Criar uma nova sessão
  • Configurar o diretório de trabalho
  • Fechar a entrada padrão, a saída padrão e a saída de erro padrão
  • Executar o serviço proposto, que vai logar a contagem a cada um segundo

Aqui está a descrição completa do exemplo

Criação pela system call

A system call daemon capaz de abstrair tudo isso em uma única chamada

O mesmo exemplo usando daemon system call

Conclusão

Neste artigo foi apresentado como se utiliza o fork através de alguns exemplos simples, e como utilizar o clone para invocar um outra aplicação utilizando o comando exec, dessa forma podemos criar serviços para prover algumas funcionalidades para o sistema na forma de daemon. No próximo artigo apresentarei o primeiro IPC o PIPE.

Referências

Notificações
Notificar
guest
1 Comentário
recentes
antigos mais votados
Inline Feedbacks
View all comments
Caio Toledo
13/04/2021 20:58

Parabéns pelo artigo Cristiano!
Excelente conteúdo! Que venham mais artigos =D

WEBINAR

Visão Computacional para a redução de erros em processos manuais

DATA: 23/09 ÀS 17:00 H