Académique Documents
Professionnel Documents
Culture Documents
SISTEMAS
OPERACIONAIS
Trabalho 2 – Estudo e aplicação de subprocessos
Integrantes
fork()
......................................................................................................................................................3
exec() .....................................................................................................................................................3
execl() ....................................................................................................................................................3
wait() .....................................................................................................................................................3
exit() ......................................................................................................................................................4
getpid() ..................................................................................................................................................4
getppid() ................................................................................................................................................4
Β) EXECUTE O PROGRAMA (PROG1) EM ANXO EM UM AMBIENTE LINUX E RESPONDA ÀS
SEGUINTES PERGUNTAS
b1) Qual o retorno esperado de cada um dos comandos fork() e do comando execl()? ......................4
b2) No caso do presente código, qual a resposta correta para o comando: printf(“Resultado: o
comando foi/não foi executado com sucesso\n”)? ................................................................................4
b3) A identificação do processo pai (PID) será sempre maior ou menor que a dos processos filho?
Justifique. ..............................................................................................................................................4
b4) identificação (PID) é sempre atribuída de forma seqüencial ou pode ser aleatória? Justifique.
..5
b5) Em quantos processos resulta a execução deste programa? Quais são eles? Que parte do código
cada um executa? ..................................................................................................................................5
b6) Qual No segundo fork(), responda as perguntas de quem sou eu e informe quem é o processo pai
de cada um deles. ..................................................................................................................................5
b7) Qual a finalidade do comando wait()? Que valores ele pode retornar? ........................................5
b8) Para que serve a variável status? Que valores ela pode receber e o que eles significam?............5
b9) O comando printf() seguinte ao comando execl() é geralmente executado ou não? Apresente suas
conclusões para tal comportamento. ....................................................................................................5
b10) Para os possíveis casos de 9, como funcionaria o comando exit()? ............................................6
b11) Altere o comando execl() para executar corretamente o comando “pwd” e discuta o resultado
global da execução.
...............................................................................................................................6
Χ) EXECUTE O PROGRAMA (PROG2) EM ANEXO EM UM AMBIENTE LINUX E RESPONDA ÀS
SEGUINTES PERGUNTAS:
c1) Monte e mostre a árvore genealógica da família de processos. .....................................................6
c2) Execute o programa por algum número de vezes, verifique a dinâmica e a ordem em que as
coisas acontecem. Quais suas conclusões?
...........................................................................................6
c3) Aumente para 3 o número de “maxsubprocs” e monte novamente a árvore genealógica da
família. Dê uma justificativa para a nova estrutura da árvore. ............................................................6
c4) Para que serve a variável “j”? .......................................................................................................6
c5) Substitua Substitua a instrução “for (i = j; i < maxsubprocs; i++)” por “for (i = 0; i <
maxsubprocs; i++)” e veja o que acontece. Descreva e Justifique o ocorrido. ...................................6
c6) Verifique o valor das variáveis vistas por cada processo e explique como funciona o escopo das
mesmas. .................................................................................................................................................6
2
c7) Mova a declaração da variável “dado2” para dentro da rotina main() e compare os resultados
com os obtidos em c.6. ..........................................................................................................................6
∆) PROCESSOS COOPERATIVOS
d1) Experimento 1 .................................................................................................................................7
d2) Experimento 2. ................................................................................................................................7
• Descreva os comandos: fork(); exec(); execl(); wait(); exit(); getpid() e getppdi().
fork()
Este comando é a única chamada de sistema que possibilita a criação de um
processo em UNIX. Os processos pai e filho partilham o mesmo código. O segmento
de dados do usuário do novo processo (filho) é uma cópia exata do segmento
correspondente ao processo antigo (pai). Por outro lado, a cópia do segmento de
dados do filho do sistema pode diferir do segmento do pai em alguns atributos
específicos (como por exemplo, o pid, o tempo de execução, etc.). Os filhos
herdam uma duplicata de todos os descritores dos arquivos abertos do pai (se o
filho fecha um deles, a cópia do pai não será modificada). Mais ainda, os
ponteiros para os arquivos associados são divididos (se o filho movimenta o
ponteiro dentro de um arquivo, a próxima manipulação do pai será feita a partir
desta nova posição do ponteiro). Esta noção é muito importante para a
implementação dos pipes (tubos) entre processos.
Tem como valores de retorno 0 para o processo filho, e o identificador do processo filho para o
processo pai; e 1 em caso de erro, pois o sistema suporta a criação de um número limitado de
processos.
exec()
O comando exec() troca o processo corrente pelo novo que foi especificado. Se a
função retorna, um erro terá ocorrido. O valor de retorno é -1 neste caso, e a
variável global errno será setada para indicar o erro.
execl()
O comando execl() significa execute and leave, ou seja, executa e termina o
comando indicado pelo pathname com as opções indicadas pelos restantes
argumentos da função. Este comando requer que cada um dos argumentos da linha de
comando passada ao novo programa seja especificada por argumentos em separado. O
último argumento é o NULL pointer. Assim como exec(), se a função retorna, um
erro terá ocorrido. Neste caso, o valor de retorno é -1, e a variável global
errno será setada para indicar o erro.
3
wait()
A função wait suspende a execução do processo até a morte de seu filho. Se o filho já estiver
morto no instante da chamada da primitiva (caso de um processo zumbi), a função retorna
imediatamente. Os possíveis valores de retorno são o identificador do processo morto ou 1 em caso
de erro.
exit()
O comando exit() provoca o término do programa em execução. Este
comando não retorna nenhum valor.
getpid()
O comando getpid() retorna o identificador do processo corrente.
getppid()
O comando getppid() retorna o identificador do processo pai do
processo corrente.
b. Execute o programa (prog1) em anexo em um ambiente LINUX e responda às seguintes
perguntas:
b.1 Qual o retorno esperado de cada um dos comandos fork() e do comando execl()?
O valor esperado de ambos os comandos fork() são 0 para o processo criado recentemente,
isto é, o processo filho e também o identificador do processo filho para o processo pai, cujo valor
pode ser obtido através do comando getpid(). O valor esperado do comando execl(), se houver
retorno, será 1, indicando que um erro terá sido ocorrido.
b.2 No caso do presente código, qual a resposta correta para o comando:
printf(“Resultado: o comando foi/não foi executado com sucesso\n”)?
Resultado: o comando não foi executado com sucesso,
4
b.3 A identificação do processo pai (PID) será sempre maior ou menor que a dos processos
filho? Justifique.
A identificação do processo pai será sempre menor que a dos processos filho, pois os
identificadores dos processos filho são normalmente gerados sequencialmente, o que implica que
um processo gerado mais recentemente, no caso o processo filho, não possa ter seu identificador
maior que a do seu pai.
b.4 A identificação (PID) é sempre atribuída de forma seqüencial ou pode ser aleatória?
Justifique.
A identificação (PID) é normalmente gerada de forma seqüencial, pois só pode haver um processo
rodando na CPU e existem vários outros processos nas filas, o que faz com que eles recebam
números seqüenciais.
b.5 Em quantos processos resulta a execução deste programa? Quais são eles? Que parte do
código cada um executa?
A execução deste programa resulta em 3 processos. Um processo é o que estava sendo executado e
os outros 2 são criados através dos comandos fork(). O primeiro processo executa o bloco else mais
externo e depois o bloco else interno. O segundo processo executa o bloco else dentro do bloco if
mais externo ao passo que o terceiro processo, executa o bloco if dentro do bloco if mais externo.
b.6 No segundo fork(), responda as perguntas de quem sou eu e informe quem é o processo pai
de cada um deles.
Quem sou eu é o processo criado menos recentemente, logo será o FILHO, ao passo que E eu quem
sou será o processo criado mais recentemente, que nesse caso será o NETO.
b.7 Qual a finalidade do comando wait()? Que valores ele pode retornar?
A finalidade do comando wait() é suspender a execução do processo corrente até que a execução do
5
seu filho seja terminada. Ele pode retornar o identificador do processo que mudou seu estado.
b.8 Para que serve a variável status? Que valores ela pode receber e o que eles significam?
A variável status serve para informar ao processo principal o status de término do filho através de
seus bits setados. Ela pode receber 0 ou 1, sendo que 0 significa que o filho terminou com sucesso e
1 caso contrário.
b.9 O comando printf() seguinte ao comando execl() é geralmente executado ou não?
Apresente suas conclusões para tal comportamento.
O comando printf() seguinte ao comando execl() não é geralmente executado mesmo que o
comando execl() retorne 1, indicando algum erro.
b.10 Para os possíveis casos de 9, como funcionaria o comando exit()?
O comando exit() ativa o wait que o pai faz, encerrando o neto com um estado anômalo. Nesse caso,
o exit() avisa que o pai deve imprimir na tela um aviso ao usuário dizendo que o comando execl()
não foi executado e que o neto foi finalizado com erro.
b.11 Altere o comando execl() para executar corretamente o comando “pwd” e discuta o
resultado global da execução.
execl ("/bin/pwd","pwd",0);
O comando execl() foi alterado para executar o comando pwd, que lista o diretório corrente da
aplicação. A imagem do processo foi alterada pela do processo pwd (o path da execução do
programa carregado por execl encontrase no primeiro argumento de chamada da função), o
comando pwd executado, o processo finalizado e a imagem original do processo filho restaurada.
c. Execute o programa (prog2) em anexo em um ambiente LINUX e responda às seguintes
perguntas:
6
c.1 Monte e mostre a árvore genealógica da família de processos.
c.2 Execute o programa por algum número de vezes, verifique a dinâmica e a ordem em que
as coisas acontecem. Quais suas conclusões?
Na maioria das vezes, ocorre a criação de um processo pai a partir do processo principal (Init),
seguida da criação do primeiro processo filho desse pai, criação de um neto a partir do primeiro
filho gerado e finalmente a criação do segundo processo filho.
c.3 Aumente para 3 o número de “maxsubprocs” e monte novamente a árvore genealógica da
família. Dê uma justificativa para a nova estrutura da árvore.
c.4 Para que serve a variável “j”?
c.5 Substitua a instrução “for (i = j; i < maxsubprocs; i++)” por “for (i = 0; i < maxsubprocs;
i++)” e veja o que acontece. Descreva e Justifique o ocorrido.
7
c.6 Verifique o valor das variáveis vistas por cada processo e explique como funciona o escopo
das mesmas.
c.7 Mova a declaração da variável “dado2” para dentro da rotina main() e compare os
resultados com os obtidos em c.6.
d. Processos Cooperativos
d.1) Experimento 1
Construa uma aplicação utilizando o conceito de processos filhos de forma a atender os
seguintes requisitos:
P1 possui um Loop para gerar 5 números aleatórios entre 5 e 25. Para cada número par
gerado cria um subprocesso P2 e envia o número para ele; para cada número ímpar cria um
subprocesso P3 e envia o número para ele. P3 calcula a série de Fibonacci com o valor do
número recebido e envia o resultado a P1; P4 calcula a permutação com o valor do número
recebido e envia o resultado a P1; P1 mostra os resultados recebidos: a classificação feita se
par ou ímpar, a operação realizada (Fibonacci ou Permutação) e o resultado recebido do
processo que realizou o cálculo.
d.2) Experimento 2
Construa uma aplicação utilizando o conceito de processos filhos de forma a atender os
seguintes requisitos:
P1 possui duas matrizes, uma de 1x5 e outra de 5x8 valores inteiros e precisa calcular o
produto das mesmas. P1 gera suprocessos de forma a paralelizar a execução, cada um realiza
o cálculo de um dos produtos; Ao final P1 apresenta a matriz resultado.
8
9