Criação de Processos Fork( ) Exec( ) 8/23/18 1
Chamadas de Sistema: Process Management 2
Chamada fork( ) / exec( ) 3
Esboço de uma shell while (TRUE) { /* repeat forever */ type_prompt( ); /* display prompt */ read_command (command, parameters) /* input from terminal */ if (fork()!= 0) { /* fork off child process */ /* Parent code */ waitpid( -1, &status, 0); /* wait for child to exit */ } else { /* Child code */ execve (command, parameters, 0); /* execute command */ } } 4
As variantes de exec() #include <unistd.h> int execl(const char *path, const char *arg0,... /*, (char *)0 */); int execv(const char *path, char *const argv[]); int execle(const char *path, const char *arg0,... /*, (char *)0, char *const envp[]*/); int execve(const char *path, char *const argv[], char *const envp[]); int execlp(const char *file, const char *arg0,... /*, (char *)0 */); int execvp(const char *file, char *const argv[]);
Argumentos de linha de comando Quando um processo filho é criado o processo pai, que fazr o exec, pode passar argumentos para o programa, como se fosse na console (na shell). >> show-arguments 3 5 argc = 3 argv[0] = show-arguments, argv[1] = 3 e argv[2] = 5
Environment List A cada programa é dado acesso a uma lista de variáveis de ambiente (enrironment variables). No caso de processos criados por fork, inicialmente herdam a environment list do processo pai. Essa lista é acessada via ponteiro environ: e cada elemento da lista é um ponteiro para um endereço de uma string seguindo a convenção VAR-NAME=value\0.
Entregável Um relatório (em um único arquivo, ASCII) c/ sufixo txt contendo, para cada exercício resolvido: l Nome da Dupla l O enunciado l Código fonte do programa(s) l A chamada do programa e sua saída l Uma discusão sobre o motivo de ter obtido esse resultado Enviar o relatório para fbeneditovm@gmail.com e endler@inf.puc-rio.br até o sabado, as 12:00
Perguntas?
URL dos Labs www.inf.puc-rio.br/~endler/courses/inf1019/ transp/aulas-praticas
Exercícios 1) Faça um programa para criar dois processos, o pai escreve seu pid e espera o filho terminar e o filho escreve o seu pid e termina. 2) Agora, usando a mesma estrutura de processos pai e filho, declare uma variável visível ao pai e ao filho, no pai inicialize a variável com1 e imprima seu valor antes do fork(). No filho, altere o valor da variável para 5 e imprima o seu valor antes do exit(). Agora, no pai, imprima novamente o valor da variável após o filho ter alterado a variável - após a waitpid(). Justifique os resultados obtidos. 3) Use o programa anterior para ler e ordenar um vetor de 10 posições. O filho ordena o vetor e o pai exibe os dados do vetor antes do fork() e depois do waitpid(). Eles usarão o mesmo vetor na memória? Justifique. 4) Modifique o programa anterior para que o filho execute um programa elaborado por você, que mande imprimir uma mensagem qualquer no vídeo, por exemplo, alo mundo. Em seguida altere o programa do item 4 para o filho executar o programa echo da shell. 11
Exercícios 1a) Faça um programa composto por dois processos, processo pai e processo filho, onde: o Pai - Imprime o seu pid, espera o filho terminar e imprime "Pai finalizado". o Filho - Imprime o seu pid e o pid do seu pai, e no final imprime "Filho finalizado". DICA: Procure na internet o comando para obter o PID (process id) de um processo. 1b) Crie processos pai e filho, e Crie uma variável visível ao pai e ao filho iniciada com 0. O pai deve somar 50 a esta variável e imprimir: Pai <PID> - <valor>. O filho deve somar 10 a esta variável e imprimir: Filho <PID> - <valor>. O pai deve esperar o processo filho terminar e imprimir novamente o valor da variável: Pai após <PID> - <valor>. O que você observou sobre o valor da variável no pai e no filho? Explique o por quê deste comportamento. DICA: Para descobrir os protótipos das funções fork e waitpid execute o comando man no Terminal para acessar o manual: "man fork" e "man waitpid". 12
Exercícios 2) Faça um programa em que três processos q executam paralelamente as seguintes ações: Pai - Imprime os números de 1 a 50, com um intervalo de 2 segundos entre cada número. Após imprimir todos os números, imprime a frase Processo pai vai morrer. Filho1 - Imprime os números de 100 a 200, com um intervalo de 1 segundo entre cada número. Antes de imprimir os números, imprime a frase Filho 1 foi criado, e após imprimir todos os números, imprime a frase Filho 1 vai morrer. Neto1- (filho do processo Filho1) imprime os números de 300 a 350, com um intervalo de 2 segundos entre cada número. Antes de imprimir os números, imprime a frase Neto 1 foi criado Após imprimir todos os números, imprime a frase Neto 1 vai morrer. Importante: Em cada printf os processos devem imprimir o seu pid e o pid do seu pai. DICA: sleep(1) bloqueia o processo por 1 segundo. É possível ver os processos executando em paralelo? Que alterações devem ser feitas em seu programa para que primeiro sejam exibidos só os prints do neto, depois só os do filho e depois só os do pai? 13
Exercícios 3) Crie um programa que realize o print da frase: "Alô mundo", no arquivo alomundo.c. Compile este programa. Em seguida, crie um programa que execute o programa alomundo criado por você. Importante: Utilize alguma função da família "execv" para realizar esta atividade. Para conhecer os protótipos das funções disponíveis execute o comando man no Terminal para acessar o manual: "man execv".
Transparências das aulas praticas na URL: www.inf.puc-rio.br/~endler/courses/inf1019/transp