Linguagem de Programação IV
Post on 12-Jan-2016
25 Views
Preview:
DESCRIPTION
Transcript
Linguagem de Programação IV
Carlos Oberdan Rolim
Ciência da ComputaçãoSistemas de Informação
Criação de processos paralelos
*baseado no material do Prof. Edison Ishikawa
Como iniciar um processo em C?
Similar a rodar um programa na linha de comando
Usando a família de chamadas de sistemas exec…(…)
exec, execl, execv, execve, …
exec…() troca o processo corrente pelo novo que foi
especificado
Exec....
O processo que chamou exec... É completamente substituído pelo novo programa, e o novo programa inicia sua execução como se fosse a função principal (main).
Não existe a criação de um novo processo mas sim a substituição do programa em execução
Com fork cria-se novos processos
Com exec inicia-se novos programas
Exec – Diferentes funções
#include <unistd.h>
extern char **environ;
int execl( const char *path, const char *arg, ...);
int execle( const char *path, const char *arg , ..., char* const envp[]);
int execlp( const char *file, const char *arg, ...);
int execv( const char *path, char *const argv[]);
int execvp( const char *file, char *const argv[]);
Exec
Diferenças
os execl(), para o qual o número de argumentos do programa
lançado é conhecido;
os execv(), para o qual esse número é desconhecido.
Em outras palavras, estes grupos de primitivas se
diferenciam pelo número de parâmetros passados.
Exec
Diferenças
Modo de passar os argumentos
l = lista
execl, execlp, execle
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 - (char *) 0
Ex: char* arg0, char* arg1,....,char *argn, (char *) 0
v = vetor
execv, execvp, execve
Os argumentos são passados em um array de ponteiros, e o endereço deste array é passado como argumento
Exec
PropriedadesO novo programa herda do processo que o invoca
Process ID e parent process IDReal user ID and real group IDSupplementary group IDsProcess group IDSession IDControlling terminalTime left until alarm clockCurrent working directoryRoot directoryFile mode creation maskFile locksProcess signal maskResource limitstms_utime, tms_stime, tms_cutime and tms ustime values
execv() - exemplo
int execv(const char *path, char *const argv[])
path - command path
argv - argumentos (por um null no final)
Exemplo
char* prog[3]={“/usr/bin/ps”, “-a”, NULL};
execv(prog[0], prog);
Sugestão
consulte o man
execv – exemplo
//gcc -o execv execv.c
//Existem diversas chamadas execXXX
#include <stdio.h>
#include <stdlib.h>
int main(){
char *my_program[3] = {"/bin/ls", "-l“,NULL};
execv(my_program[0],my_program);
printf("Cannot execute the command.\n");
return 0;
}
Como executar vários processo em um único programa C?
System call fork()
quando um processo é “forkeado”, um novo processo
é criado
o segmento de dados e códigos do novo processo é o
mesmo do original
uma entrada na tabela de processos é criada para o
novo processo
Fork
Processo 1
shell
fork
fork
Processo 1
Processo 2
PAI
FILHO
shell
shell exec
shell
ps
System call fork
Copia o processo corrente e o executa
valor de retorno
ZERO no processo filho
O Id do processo filho (PID) no processo pai
use o valor de retorno para identificar aonde o
programa está
Exemplo de fork
#include < stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
if (fork()==0) {
printf(“Eu sou o filho\n”);
} else {
printf(“Eu sou o pai\n”);
}
}
Cria o processo filho
Código executado pelo filho
Código executado pelo pai
Comportamento fork
Comportamento do fork
Sequencia fork() + execve()
Fork vs Execve()
O que acontece com o processo filho quando ele morre antes que o pai?
Zombie
Quando o processo filho termina, ele tem que avisar o pai
antes de se matar
Se o pai não tomar conhecimento da morte do filho, o filho
se tornará um Zombie
O filho ficará no estado Zombie até que o pai tome
conhecimento
Zombie
Os recursos usados pelo Zombie não são liberados!
Os processos zombie são rotulados como
<defunct> na listagem do comando
ps -u username
Se o seu programa(pai) rodar por muito tempo,
criando zombies, ele irá esgotar a memória
É obrigação do programador (sua) evitar isso
Exemplo de zombie
#include <stdio.h>
#include <stdlib.h>
int main(){
int pid;
pid = fork();
if (pid==0){
printf(“I am child. I become a zombie now.\n”);
exit (0); child process terminate here
} else {
printf(“I am parent. I loop here. My child pid is [%d]\n”, pid);
while(1); parent process continue to run
}
return 0;
}
# ./zombie
I am parent. I loop here. My child pid is [2966]
I am child. I become a zombie now.
Saída do ps -ax
2965 pts/0 R+ 0:24 ./zombie
2966 pts/0 Z+ 0:00 [zombie] <defunct>
Como evitar o Zombie
Usando a system call wait e waitpid no processo pai para tomar conhecimento da morte do filho
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.
A função waitpid suspende a execução do processo até que o filho especificado pelo argumento pid tenha morrido. Se ele já estiver morto no momento da chamada, o comportamento é idêntico ao descrito anteriormente.
Esperar pela terminação
Chamado também de join
Wait: cenários possíveis
Wait e Waitpid
#include <sys/types.h> #include <sys/wait.h>
pid_t wait(int *status) /* espera a morte de um filho */ pid_t waitpid(pid_t pid, int *status, int options)
int *status /* status descrevendo a morte do filho */
Valor de retorno: identificador do processo morto ou -1 em caso de erro.
Wait e Waitpid
O valor do argumento pid pode ser:
< -1 : significando que o pai espera a morte de qualquer filho cujo o ID do grupo é igual so valor de pid;
-1 : significando que o pai espera a morte de qualquer filho;
0 : significando que o pai espera a morte de qualquer processo filho cujo ID do grupo é igual ao do processo chamado;
> 0 : significando que o pai espera a morte de um processo filho com um valor de ID exatamente igual a pid.
Wait e Waitpid
Se status é não nulo (NULL), wait e waitpid armazena a informação relativa a razão da morte do processo filho, sendo apontada pelo ponteiro status. Este valor pode ser avaliado com diversas macros que são listadas com o comando shell # man 2 wait.
O código de retorno via status indica a morte do processo que pode ser devido uma:
uma chamada exit(), e neste caso, o byte à direita de status vale 0, e o byte à esquerda é o parâmetro passado a exit pelo filho;
uma recepção de um sinal fatal, e neste caso, o byte à direita de status é não nulo. Os sete primeiros bits deste byte contém o número do sinal que matou o filho.
Exemplo
St é um ponteiro global que recebe o retorno de
wait
Exemplo
Exemplo
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(){
int pid;
pid = fork();
if (pid==0){
printf(“I am child.\n”);
exit (0); o processo filho termina aqui
} else {
printf(“I am parent. My child pid is [%d]\n”, pid);
wait(NULL); espera o filho aqui
while(1);
}
return 0;
}
# ./zombie2
I am parent. My child pid is [2982]
I am child.
Saída do ps -ax
2981 pts/0 R+ 0:04 ./zombie2
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>
int main(void){ pid_t child_pid, wpid; int status = 0; int i; int a[3] = {1, 2, 1};
printf("parent_pid = %d\n", getpid()); for (i = 0; i < 3; i++) { printf("i = %d\n", i); if ((child_pid = fork()) == 0) { printf("In child process (pid = %d)\n", getpid()); if (a[i] < 2) { printf("Should be accept\n"); exit(1); } else{ printf("Should be reject\n"); exit(0); } /*NOTREACHED*/ } } while ((wpid = wait(&status)) > 0) { printf("Exit status of %d was %d (%s)\n", (int)wpid, status, (status > 0) ? "accept" : "reject"); } return 0;}
Saída:
parent_pid = 15820i = 0i = 1In child process (pid = 15821)Should be accepti = 2In child process (pid = 15822)Should be rejectIn child process (pid = 15823)Should be acceptExit status of 15823 was 256 (accept)Exit status of 15822 was 0 (reject)Exit status of 15821 was 256 (accept)
Criando dados compartilhados - IPC
shmget vs mmap
Bibliografia
Operating Systems, 4th Ed, William Stallings, Prentice Hall
Advanced Programming in the UNIX Environment, W. R.
Stevens, Addison-Wesley
Programming with GNU Software, M. Loukides e A. Oram,
O'Reilly
Managing Projects with make, A. Oram e S. Talbott, O'Reilly
top related