Você está na página 1de 3

Relatório de Sistemas Operacionais

Professora: Valéria Q. Reis


Aluno: Felipe Lira de Oliveira

No arquivo example_to_be_completed.c, há um exemplo de programa que cria um


processo filho semelhante ao processo pai. Considerando esse código, qual seria a função
responsável por criar um novo processo?

Resposta: A função fork() é a responsável por criar um novo processo neste código.

Descreva como essa função funciona e o que ela retorna como parâmetro.

A função fork() cria um processo filho exatamente igual ao processo que o chamou. O
processo chamado é referido como filho e o processo que o chama é referido como pai.
Ao obter sucesso em criar o processo filho, o fork() retorna o PID (Process Identifier) do
filho no pai, enquanto o PID = 0 é retornado ao filho. Porém, se houver falha, o valor -1 é retornado
ao pai e nenhum processo filho é criado.

Atente para o aparecimento de duas novas funções: getpid e getppid. O que elas fazem?

A função getpid() retorna o PID do processo chamado (filho).

A função getppid() retorna o PID do processo pai do que foi chamado; que será ID do
processo que criou o filho, ou caso o pai tenha terminado, será o ID do processo ao qual o filho foi
reparentado.

Tente compilar o programa (gcc -o example example_to_be_completed.c). Quais erros


são reportados? Por que?

Erros verificados no terminal:

example_to_be_completed.c:23:5: error: unknown type name ‘pid_t’


23 | pid_t childpid;
| ^~~~~
example_to_be_completed.c:25:2: warning: implicit declaration of function ‘printf’ [-
Wimplicit-function-declaration]
25 | printf("Começando o programa...\n");
| ^~~~~~
example_to_be_completed.c:25:2: warning: incompatible implicit declaration of built-in
function ‘printf’
example_to_be_completed.c:1:1: note: include ‘<stdio.h>’ or provide a declaration of
‘printf’
+++ |+#include <stdio.h>
1 | /*
example_to_be_completed.c:27:20: warning: implicit declaration of function ‘fork’ [-
Wimplicit-function-declaration]
27 | childpid = fork();
| ^~~~
example_to_be_completed.c:30:13: warning: implicit declaration of function ‘perror’ [-
Wimplicit-function-declaration]
30 | perror("Falha ao criar filho com fork()\n");
| ^~~~~~
example_to_be_completed.c:35:131: warning: implicit declaration of function ‘getpid’ [-
Wimplicit-function-declaration]
35 | printf("Vc esta no processo filho. O pid desse processo eh %ld. O pid do
processo pai desse processo eh %ld\n", (long)getpid(), (long)getppid());
| ^~~~~~
example_to_be_completed.c:35:147: warning: implicit declaration of function ‘getppid’ [-
Wimplicit-function-declaration]
35 | printf("Vc esta no processo filho. O pid desse processo eh %ld. O pid do
processo pai desse processo eh %ld\n", (long)getpid(), (long)getppid());
| ^~~~~~~
example_to_be_completed.c:21:14: warning: unused parameter ‘argv’ [-Wunused-
parameter]
21 | int main(int argv, char *argc[])
| ~~~~^~~~
example_to_be_completed.c:21:26: warning: unused parameter ‘argc’ [-Wunused-
parameter]
21 | int main(int argv, char *argc[])
| ~~~~~~^~~~~~

Todos os erros reportados são de declaração implícita de funções que não estão visíveis no
código. É necessário importar as bibliotecas que contêm essas funções.

Conserte o código e execute o programa (./example) Analise o que acontece em relação


às mensagens impressas na tela. Pode-se dizer que há uma sequência que aconteça 100% das
vezes? Por que?

Na maioria das vezes, a sequência pai – filho acontece, mas não é em 100% dos casos,
porque não há determinismo em qual dos processos irá executar primeiro. Em processadores multi-
core, os processos pai e filho podem até executar em paralelo.

Agora, comente a primeira main e descomente a segunda. Nesse novo código, novos
processos são criados em três etapas semelhantes à da main anterior. Sem executar o código,
quantos processos você acha que serão criados? Compile e execute o código e veja o resultado ;)
Justifique o número encontrado.

Eu pensava que seriam executados 6 processos, mas o resultado na execução foi de 8


processos. Isso acontece porque o loop faz a criação de processos com o fork() aumentar
exponencialmente, sendo assim: como o for é iterado 3 vezes e em cada vez há um fork(), teremos
2³ = 8 processos.

Se você executar o código example várias vezes poderá ter a chance de ver um ou mais
processos filhos referenciarem ao processo init, de pid 1, como pai. No entanto, ao traçar o
mapa de criações de processos, nota-se que de início os processos filhos tinham outros processos
como pai. Por que isso acontece?

Isso acontece porque alguns processos filhos podem ter sido reparentados na árvore de
processos quando o processo pai original terminou.

Considerando o código da seção anterior, como faríamos para mudar a imagem do


processo filho e fazê-lo executar outro código? É essa mudança de imagem que
iremos usar no código shell_to_be_completed.c. Trata-se de um código simulador de
terminal onde é possível digitar comandos a serem executados pelo SO. Pode-se, por
exemplo, pedir para o programa executar o comando “ls -l” o qual lista os arquivos e diretórios
da pasta local.

Para mudar a imagem do processo filho, é necessário usar a função exec(), há diversas
funções advindas dessa, como execl(), execv(), execvpe(), entre outros.

Se um processo filho é executado em background, então seu processo pai não precisa
esperar pelo término do mesmo para disponibilizar o prompt ao usuário novamente. Caso
contrário, o prompt fica bloqueado até que o processo filho seja finalizado. Aliás, qual função
realiza uma chamada ao sistema que faz com que um processo pai espere pelo término de um de
seus processos filhos?

A função wait() faz o processo pai esperar que o processo filho termine para então
continuar sua execução

Você também pode gostar