1 / 35

Linguagem de Programação IV

Linguagem de Programação IV. Carlos Oberdan Rolim Ciência da Computação Sistemas 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

kolina
Download Presentation

Linguagem de Programação IV

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linguagem de Programação IV Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

  2. Criação de processos paralelos *baseado no material do Prof. Edison Ishikawa

  3. 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

  4. 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

  5. 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[]);

  6. 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.

  7. 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

  8. Exec • Propriedades • O novo programa herda do processo que o invoca • Process ID e parent process ID • Real user ID and real group ID • Supplementary group IDs • Process group ID • Session ID • Controlling terminal • Time left until alarm clock • Current working directory • Root directory • File mode creation mask • File locks • Process signal mask • Resource limits • tms_utime, tms_stime, tms_cutime and tms ustime values

  9. 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

  10. 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; }

  11. 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

  12. Processo 1 Processo 1 fork Processo 2 shell shell shell fork shell ps exec Fork PAI FILHO

  13. 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á

  14. 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

  15. Comportamento fork

  16. Comportamento do fork

  17. Sequencia fork() + execve()

  18. Fork vs Execve()

  19. O que acontece com o processo filho quando ele morre antes que o pai?

  20. 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

  21. 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

  22. Exemplo de zombie # ./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> #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; }

  23. 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.

  24. Esperar pela terminação Chamado também de join

  25. Wait: cenários possíveis

  26. Waitpid

  27. Exemplo

  28. Exemplo

  29. Exemplo # ./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 <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; }

  30. /* arquivo test_wait1.c */ #include <errno.h> #include <signal.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { int pid ; printf("\nBom dia, eu me apresento. Sou o processo %d.\n",getpid()) ; printf("Estou sentindo uma coisa crescendo dentro de minha barriga..."); printf("Sera um filho?!?!\n") ; if (fork() == 0) { printf("\tOi, eu sou %d, o filho de %d.\n",getpid(),getppid()) ; sleep(3) ; printf("\tEu sao tao jovem, e ja me sinto tao fraco!\n") ; printf("\tAh nao... Chegou minha hora!\n") ; exit(7) ; } else { int ret1, status1 ; printf("Vamos esperar que este mal-estar desapareca.\n") ; ret1 = wait(&status1) ; if ((status1&255) == 0) { printf("Valor de retorno do wait(): %d\n",ret1) ; printf("Parametro de exit(): %d\n",(status1>>8)) ; printf("Meu filho morreu por causa de um simples exit.\n") ; } else printf("Meu filho nao foi morto por um exit.\n") ;

  31. printf("\nSou eu ainda, o processo %d.", getpid()); printf("\nOh nao, recomecou! Minha barriga esta crescendo de novo!\n"); if ((pid=fork()) == 0) { printf("\tAlo, eu sou o processo %d, o segundo filho de %d\n", getpid(),getppid()) ; sleep(3) ; printf("\tEu nao quero seguir o exemplo de meu irmao!\n") ; printf("\tNao vou morrer jovem e vou ficar num loop infinito!\n") ; for(;;) ; } else { int ret2, status2, s ; printf("Este aqui tambem vai ter que morrer.\n") ; ret2 = wait(&status2) ; if ((status2&255) == 0) { printf("O filho nao foi morto por um sinal\n") ; } else { printf("Valor de retorno do wait(): %d\n",ret2) ; s = status2&255 ; printf("O sinal assassino que matou meu filho foi: %d\n",s) ; } } } exit(0); }

  32. # ./test_wait Bom dia, eu me apresento. Sou o processo 3015.Estou sentindo uma coisa crescendo dentro de minha barriga...Sera um filho?!?!Vamos esperar que este mal-estar desapareca. Oi, eu sou 3016, o filho de 3015. Eu sao tao jovem, e ja me sinto tao fraco! Ah nao... Chegou minha hora!Valor de retorno do wait(): 3016Parametro de exit(): 7Meu filho morreu por causa de um simples exit.Sou eu ainda, o processo 3015.Oh nao, recomecou! Minha barriga esta crescendo de novo!Este aqui tambem vai ter que morrer. Alo, eu sou o processo 3017, o segundo filho de 3015 Eu nao quero seguir o exemplo de meu irmao! Nao vou morrer jovem e vou ficar num loop infinito! Saída do ps –ax 3015 pts/0 S+ 0:00 ./test_wait 3017 pts/0 R+ 0:17 ./test_wait

  33. Criando dados compartilhados - IPC

  34. shmget vs mmap

  35. 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

More Related