Você está na página 1de 46

Sumrio

Tcnicas Avanadas de Programao


Prof. Joo Marcos M. da Silva
Departamento de Engenharia de Telecomunicaes
Escola de Engenharia
Universidade Federal Fluminense

Agosto de 2011

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 1/33

Sumrio

Sumrio

Processos Concorrentes I

Exerccios

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 2/33

Sumrio

Sumrio

Processos Concorrentes I

Exerccios

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 2/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Sumrio

Processos Concorrentes I
Introduo
Identificao de Processos
Primitivas

Exerccios

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 3/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Sobre os processos

Os processos so programas carregados na memria do


computador e podem ser classificados como pesados ou leves.
Processos Pesados
Os processos pesados so os programas tradicionais, possuindo um
conjunto de operaes iniciais bsicas que comeam a sua
execuo. Estas operaes iniciais so o que chamamos de thread.
A funo void main de um programa escrito em C uma thread
inicial.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 4/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Sobre os processos

Ateno
importante entender que cada programa , ao menos, um
processo e que cada processo possui uma srie de atributos:
PID
PPID
UID e GID
etc...

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 5/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo

PID O Process Identification um nmero de


identificao nico. O primeiro processo chama-se
init e recebe o PID de nmero 1;
PPID Nenhum processo executado de forma independente
dos outros. Todos os processos no sistema, com
exceo do init, possuem um processo pai. O atributo
Parent Process ID armazena o PID do processo pai.
UID e GID O User ID e o Group ID auxiliam para que os
processos sejam executados conforme os privilgios
de uma conta de usurio e o seu grupo associado.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 6/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo

Variveis de ambiente Cada processo herda do processo pai


algumas variveis de ambiente que guardam alguns
valores que podem ser utilizados pelo processo em
execuo;
Diretrio de trabalho Os processos tambm so associados a um
diretrio de trabalho, onde podem fazer a leitura e a
gravao em disco.=;
Temporizadores O Kernel mantm registros da hora em que os
processos so criados, bem como o tempo de CPU
que eles consomem durante a sua execuo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 7/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo
Alm de um estado de execuo (ready, wait e exec), um processo
ocupa uma rea de memria formada basicamente por 3 partes:

Figure: Estrutura de um processo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 8/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo
Text Segment O segmento de cdigo contm as instrues de
mquina geradas na compilao do programa;
User Data Segment O segmento de dados de usurio contm as
variveis utilizadas pelo programa;
System Data Segment O segmento de dados do sistema contm
os valores dos registradores da CPU quando no
estiver sendo executado por algum motivo.
Ateno !
Como as instrues so separadas dos dados, possvel
compartilhar o mesmo cdigo entre vrios programas em execuo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 9/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo
Um mesmo programa pode ser ativado mais de uma vez, dando
origem a vrios processos. Nesse caso, o segmento de cdigo
compartilhado entre eles, conforme mostrado na Figura abaixo:

Figure: Compartilhamento do segmento de cdigo entre processos.


Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 10/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Atributos de um processo

Importante
Todos os processos que existam ao mesmo tempo so
concorrentes. Eles podem funcionar completamente independentes
uns dos outros, ou ocasionalmente necessitar de sincronizao e
cooperao.
Se certas operaes podem ser logicamente executadas em
paralelo, temos os chamados processos paralelos.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 11/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Racing Conditions

Racing Conditions
Suponha que 3 processos compartilham o acesso a varivel A. Dois
deles fazem operaes de modificao e um imprime o valor da
varivel.
Processo 1 A = A + 5;
Processo 2 A = A + 1;
Processo 3 Imprimir A;

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 12/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Sumrio

Processos Concorrentes I
Introduo
Identificao de Processos
Primitivas

Exerccios

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 13/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Identificando um processo
O identificador de cada processo PID fornecido pelo Sistema
Operacional. A linguagem C tem diferentes primitivas que
permitem conhecer este nmero.
Essas primitivas esto declaradas no cabealho unistd.h.
pid_t getpid() A funo getpid() retorna o nmero do processo
em execuo;
pid_t getppid() A funo getppid() retorna o nmero do processo
pai que criou o processo em execuo.
pid_t getpgrp() Esta funo retorna o GID do processo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 14/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Exemplo 1:
#include <stdio.h>
#include <unistd.h>
int main(){
printf(Eu sou o processo \%d. Meu pai o \%d. O ID do
grupo de processo o \%d.\n, getpid(),getppid(),getpgrp());
exit(0);
}
Para compilar, salve como meupid.c:
#gcc meupid.c -o meupid
#./meupid

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 15/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Sumrio

Processos Concorrentes I
Introduo
Identificao de Processos
Primitivas

Exerccios

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 15/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

A primitiva EXEC

A primitiva exec representada pelas funes:


execl()
execle()
execlp()
execv()
execve()
execvp()
Cada uma das funes desta famlia trocam a imagem do processo
em execuo pela imagem de outro processo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 16/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

A primitiva EXEC

O arquivo que ser chamado por estas funes precisa ser um


arquivo binrio ou script para ser interpretado por um outro
processo;
O arquivo precisa ter permisses de execuo;
Essas funes no retornam nenhum valor que indique seu
sucesso uma vez que o processo em execuo inteiramente
trocado pelo processo novo;
No caso de falha, as funes retornam o valor -1.
Essas funes esto declaradas em unistd.h.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 17/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

A primitiva EXEC

Ateno !
Um script, para ser interpretado no Linux, precisa iniciar com a
indicao de qual programa ser usado para a sua interpretao.
Para fazer isso, sua primeira linha deve comear com:
#!/caminho/programa

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 18/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

int execv(const char *arquivo, char const *argv[ ])


Exemplo 2:
#include <stdio.h>
#include <unistd.h>
int main{
char *cmd[] = {"cat", "/etc/passwd", (char *) 0};
printf("Vou chamar o programa cat para ler o contedo de /etc/passwd.\n");
execv("/bin/cat", cmd);
printf("Esta mensagem no ser impressa.\n");
exit(0);
}

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 19/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

A primitiva SYSTEM

A primitiva system() executa um programa especificado com


parmetro e retorna ao processo original quando este termina. O
processo original no substitudo, mas congelado.
A primitiva system() recebe apenas um nico valor, onde o
comando e seus parmetros devem ser passados como uma nica
varivel string.
Esta funo retorna -1 em caso de erro. Se for bem sucedida, a
funo retorna o cdigo de sada do programa chamado. Este
cdigo poder ser lido atravs da macro WEXITSTATUS(status).

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 19/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

int system(const char *string)

Exemplo 3:
#include <stdio.h>
#include <unistd.h>
int main{
printf("Vou chamar o programa cat para ler o contedo de /etc/issue.\n");
system("/bin/cat /etc/issue");
printf("Esta mensagem ser impressa.\n");
exit(0);
}

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 20/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

As primitivas fork() e wait() foram as primeiras para especificar


concorrncia. O fork() inicia um novo processo que compartilha o
espao de endereamento do processo pai (criador).
Ambos os processos, pai e filho, continuam a execuo em paralelo.
Esta funo retorna um valor que pode ser utilizado no controle de
execuo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 20/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

Caractersticas do fork() em Unix/Linux:


Ele duplica o processo que executa a chamada e os dois
executam o mesmo cdigo;
Cada processo tem o seu prprio espao de endereamento,
com cpia de todas as variveis, que so independentes em
relao s variveis do outro processo;
Ambos executam a instruo seguinte chamada de sistema;
O retorno da chamada fork() para o processo pai contm a
identificao do PID do processo filho recm criado;

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 21/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

O retorno da chamada fork() para o processo filho zero;


Pode-se selecionar o trecho de cdigo que ser executado
pelos processo com instruo condicional if ;
A sincronizao entre os processos pai e filho feita com a
primitiva wait(), que bloqueia o processo que a executa at
que um processo filho termine.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 22/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

int fork(void)
Exemplo 4:
#include <stdio.h>
#include <unistd.h>
int main{
int id;
id = fork();
if(id !=0)
{
printf("Eu sou o pai e espero pelo meu filho %d.\n", id);
wait(0);
printf("Meu filho acabou de terminar...vou terminar tambm!\n");
}
else
{
printf("Eu sou o filho %d e espero 10 segundos.\n", getpid());
sleep(10);
printf("J esperei e vou embora...\n");
}
}
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 22/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Exemplo 5:
#include <stdio.h>
#include <unistd.h>
int main{
int pid;
printf("Meu PID %d. Vou criar um processo filho.\n", getpid());
pid = fork();
if(pid ==0) {
printf("\t\tProcesso filho criado com PID = %d.\n", getpid());
printf("Vou ficar executando indefinidamente.\n");
for(;;);
}
else {
sleep(5);
printf("O processo pai termina e deixa o filho rfo.\n");
printf("Veja se o processo filho continua rodando com o comando\n");
printf("ps\n");
}
exit(0);
}
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 23/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

Herana entre Pai e Filho


Os processos filhos herdam uma duplicata de todos os descritores
dos arquivos abertos do processo pai. Se o processo filho
movimenta o ponteiro dentro de um arquivo, o processo pai ir
fazer a prxima movimentao na nova posio.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 23/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

Exemplo 6:
#include
#include
#include
#include
#include

<stdio.h>
<sys/types.h>
<sys/stat.h>
<fcntl.h>
<unistd.h>

int main{
int pid, fd;
char *pidnum, c;
int i, r;
printf("Meu PID %d.\n", getpid());
printf("Vou gravar meu nmero de PID no arquivo meupid.\n");
if((fd=open("meupid",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU))==-1)
{
printf("No consegui criar o arquivo meupid.\n");
exit(-1);
}
sprintf(pidnum, "%d surpresa", getpid());
if(write(fd,pidnum,15)==-1)
{
printf("No consegui escrever no arquivo.");
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 23/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

exit(-1);
}
printf("J escrevi o nmero. Fechando o arquivo.\n");
close(fd);
printf("Vou abrir o arquivo novamente para leitura.\n");
if((fd=fopen("meupid", O_RDONLY,S_IRWXU))==-1)
{
printf("No foi possvel abrir o arquivo.\n");
exit(-1);
}
printf("Vou criar um processo filho agora.\n");
pid = fork();
if(pid ==-1)
{
perror("No foi possvel criar um processo filho.\n");
exit(-1);
}
else if (pid == 0)
{
printf("\t\tSou o processo filho. Meu PID = %d.\n", getpid());
printf("\t\tVou ler o arquivo que j estava aberto pelo processo pai antes.\n")
printf("\t\tda minha criao e que eu herdei.\n");
for(i=1; i<= 5; i++)
{
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 23/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

if(read(fd,&c,1)==-1)
{
printf("No consegui ler o arquivo...");
exit(-1);
}
printf("O nmero que foi lido no arquivo %c.\n", c);
}
printf("\t\tFechando o arquivo e terminando minha execuo...\n");
close(fd);
exit(1);
}
else /* aqui comeam as instrues do processo pai. */
{
wait();
printf("O processo filho criado tinha o PID nmero %d.\n", pid);
printf("Vou ler o arquivo meupid.\n");
while((r=read(fd,&c,1)) != 0)
{
if(r == -1)
{
printf("Impossvel ler o arquivo.");
exit(-1);
}
printf("Consegui ler => %c\n", c);
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 23/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

}
printf("Meu filho leu o nmero do PID no arquivo e mexeu no meu ponteiro.\n");
printf("Terminando minha executando.\n");
close(fd);
}
exit(0);
}

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 24/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT


A primitiva wait() tem como objetivo suspender a execuo do
processo pai at que o processo filho termine a sua execuo. Esta
instruo especialmente til, principalmente para evitar
magentaracing conditions.
Outra primitiva da mesma classe a waitpid(). Ela suspende a
execuo de um determinado processo at que o processo filho,
especificado pelo PID informado, tenha terminado.
Estas primitivas retornam o valor do PID do processo que foi
terminado. Casso ocorra algo inesperado, iro retornar o valor -1.
Elas esto declaradas no cabealho wait.h.
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 24/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

A funo waitpid() precisa receber como argumento um nmero de


PID de um processo filho ou os seguintes valores predeterminados:
<-1 Um valor menor que -1 diz funo waitpid() para
suspender o processamento e esperar o trmino de
qualquer processo filho cujo valor de seu GID seja
igual ao nmero absoluto do valor passado;
-1 Diz funo para suspender o processamento at
que qualquer processo filho termine. Este o
comportamento padro;

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 25/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas FORK e WAIT

0 Diz funo para suspender o processamento at


que um processo filho com o mesmo GID do processo
pai termine;
>0 Diz funo para suspender o processamento at
que o processo filho identificado pelo PID informado
esteja terminado.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 26/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

pid_t wait(int *status) e pid_t waitpid(pid_t pid, int *status, int options)
Exemplo 7:
#include
#include
#include
#include
#include

<signal.h>
<stdio.h>
<unistd.h>
<sys/types.h>
<sys/wait.h>

int main{
int pid;
printf("\nMeu PID %d e meu GID %d. Irei criar um processo filho.\n",
getpid(), getpgrp());
if(fork() == 0) /* Instrues do processo filho. */
{
printf("\t\tProcesso filho criado. Meu PID %d e meu GID %d.\n",
getpid(), getpgrp());
sleep(4);
printf("Vou sair com cdigo 7.\n\n");
exit(7);
}
else /* Instrues do processo pai. */
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 26/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

{
int ret1, status1;
printf("Sou o processo pai. Estou esperando o processo filho.\n");
ret1 = wait(&status1);
printf("O processo filho que terminou foi o de de PID = %d.\n", ret1);
printf("Ele terminou com o parmetro de exit() = %d.\n", (status1>>8));
}
exit(0);
}

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 27/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas EXIT, ABORT e KILL

As primitivas que implementam o trmino de processos podem ser


de dois tipos:
exit() Termina o processo normalmente e seus recursos so
liberados pelo sistema operacional;
abort(pid), kill(pid) So utilizados pelo processo pai para terminar
foradamente os processos filhos.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 27/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas EXIT, ABORT e KILL

Processos Zombie
possvel que um determinado processo filho termine por algum
motivo inesperado, se torne um processo zombie (ou defunct). Os
processos zombie no podem ser terminados com o comando kill,
porque eles j no existem mais. preciso terminar o processo pai.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 28/33

Processos Concorrentes I
Exerccios

Exemplo 8: Processo zombie

Introduo
Identificao de Processos
Primitivas

(zombie.c)

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main{
int pid;
printf("Meu PID %d e vou criar um processo filho.\n", getpid());
pid = fork();
if(pid == 0) /* Aqui comeam as instrues do processo filho. */
{
printf("\t\tMeu PID %d e fui criado por %d.\n", getpid(), getppid());
printf("\t\tVerifique os processos em execuo com o comando ps.\n");
sleep(10);
printf("Processo filho terminado normalmente.\n");
exit(0);
}
else /* Aqui comeam as instrues do processo pai. */
{ for(;;);
}
}
Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 29/33

Processos Concorrentes I
Exerccios

Introduo
Identificao de Processos
Primitivas

As primitivas EXIT, ABORT e KILL

Para compilar e executar o programa, digite:


#gcc zombie.c -o zombie
#./zombie &
Para finalizar o processo zombie, digite:
#killall zombie

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 29/33

Processos Concorrentes I
Exerccios

Atributos de Processos
Identificao de Processos

Sumrio

Processos Concorrentes I

Exerccios
Atributos de Processos
Identificao de Processos

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 30/33

Processos Concorrentes I
Exerccios

Atributos de Processos
Identificao de Processos

Exerccio 1:

Em uma mquina Linux, abra um terminal e digite o comando top.


Verifique quais as informaes (colunas) so exibidas e tente
identificar algumas delas. O que voc encontrou?

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 31/33

Processos Concorrentes I
Exerccios

Atributos de Processos
Identificao de Processos

Sumrio

Processos Concorrentes I

Exerccios
Atributos de Processos
Identificao de Processos

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 32/33

Processos Concorrentes I
Exerccios

Atributos de Processos
Identificao de Processos

Exerccio 2:

Abra um terminal em uma mquina Linux e digite:


#pstree -c -p
Descreva o que voc est vendo.

Prof. Joo Marcos Meirelles da Silva

Aula 02 pg. 33/33

Você também pode gostar