Uploaded by Gabriel Calper Seabra

Threads

advertisement
Threads
Aluna: Gabriela Ross
Exercício 1
thread-create.c
#include
#include
#include
#include
<pthread.h>
<stdio.h>
<stdlib.h>
<unistd.h>
#define NUM_THREADS 16
void *threadBody (void *id) //declara o corpo da thread
{
long tid = (long) id ; //variavel para id da thread
printf ("t%02ld: Olá!\n", tid) ; //exibe o id da thread
sleep (3) ; //para o programa por 3 segundos
printf ("t%02ld: Tchau!\n", tid) ; //exibe o id da thread
pthread_exit (NULL); //encerra a thread e retorna nulo (caso n tenha erro)
}
int main (int argc, char *argv[])
{
pthread_t thread [NUM_THREADS] ; //variavel para fazer op. com threads
long i, status ; //cria variaveis
for (i=0; i<NUM_THREADS; i++) //loop para criar 16 threads
{
printf ("Main: criando thread %02ld\n", i) ;
status = pthread_create (&thread[i], NULL, threadBody, (void *) i) ;
if (status) //tratativa de erro na criacao de threads
{
perror ("pthread_create") ;
exit (1) ;
}
}
pthread_exit (NULL) ; //encerra a thread
}
Print do Terminal
Funcionamento do programa
O funcionamento desse programa é muito parecido com o anterior, a diferença
é que o método thread-join está no escopo também. Sua função é bloquear o thread de
chamada até que o thread representado por esta instância seja encerrado.
•
A ordem de criação, ativação e encerramento das threads é a mesma? Por
que?
Não. A criação ocorre na ordem crescente, seguindo a ordem do “for”, porém a
ativação e o encerramento não. Isso ocorre, pois, a execução das threads depende do
escalonamento realizada pelo sistema operacional, que executa uma parcela de código
de cada uma das threads em uma dada janela de tempo, incluindo a thread principal,
que consiste no corpo função main.
Diagrama de tempo
Exercício 2
thread-join.c
#include
#include
#include
#include
<pthread.h>
<stdio.h>
<stdlib.h>
<unistd.h>
#define NUM_THREADS 16
void *threadBody(void *id) //declara o corpo da thread
{
long tid = (long) id ; //variavel para id da thread
printf ("t%02ld: Olá!\n", tid) ; //exibe o id da thread
sleep (3) ;
//para o programa por 3 segundos
printf ("t%02ld: Tchau!\n", tid) ; //exibe o id da thread
pthread_exit (NULL) ; //encerra a thread e retorna nulo(caso n tenha erro)
}
int main (int argc, char *argv[])
{
pthread_t thread [NUM_THREADS] ; //variavel para fazer op. com threads
pthread_attr_t attr ; //variavel para inicializacao dos atributos/objetos
long i, status ; //cria variaveis
pthread_attr_init (&attr) ; //inicializa os atributos/objetos
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); //define se
a thread aguarda a execucao de outra thread relacionada ou nao
for(i=0; i<NUM_THREADS; i++) //criacao de threads
{
printf ("Main: criando thread %02ld\n", i) ;
status = pthread_create (&thread[i], &attr, threadBody, (void *) i) ;
if (status) //tratativa de erro na criacao de threads
{
perror ("pthread_create") ;
exit (1) ;
}
}
for (i=0; i<NUM_THREADS; i++)
{
printf ("Main: aguardando thread %02ld\n", i);
status = pthread_join (thread[i], NULL) ; //relaciona uma thread com ou
tra para que aguarde o termino de sua execucao
if (status) //tratativa de erro na criacao de threads
{
perror ("pthread_join") ;
exit (1) ;
}
}
pthread_attr_destroy (&attr) ; //destroy o atributo/objeto da thread
pthread_exit (NULL) ;
}
Print do Terminal
Funcionamento do programa
A função main contém um vetor de 16 posições de pthreads, para guardar as
structs das threads, que são passadas por referência para o método pthread_create, que
é encarregado de criar uma thread e inicializar uma thread. O código que será executado
pela thread está definido pelo método threadBody e é o corpo da função passado por
referência para a função pthread_create. A biblioteca pthread cria e inicia a thread no
laço for, e assim 16 threads são criadas. O tempo de processamento será escalonado
para cada thread de acordo com decisões do kernel.
• Objetivo do parâmetro attr e da chamada pthread_join
A função pthread_join vincula uma thread a outra para aguardar seu término e
retornar imediatamente quando essa finaliza utilizando o parâmetro attr como
atributo.
Diagrama de tempo
Exercício 3
thread-print.c
#include
#include
#include
#include
<pthread.h>
<stdio.h>
<stdlib.h>
<unistd.h>
#define NUM_THREADS 16
int x = 0 ; //cria variavel x e inicializa com zero
void *threadBody (void *id) //declara o corpo da thread
{
long tid = (long) id ; //variavel para id da thread
x++ ; //incrementa x
printf ("t%02ld: Olá!
(x=%02d)\n", tid, x) ; //exibe o id da thread e o
valor de x
sleep (3) ;
x++ ; //incrementa x
printf ("t%02ld: Tchau! (x=%02d)\n", tid, x) ; //exibe o id da thread e o
valor de x
pthread_exit (NULL) ; //encerra a thread e retorna nulo(caso n haja erro)
}
int main (int argc, char *argv[])
{
pthread_t thread [NUM_THREADS] ; //variavel para fazer op. com threads
long i, status ; //cria variaveis
for (i=0; i<NUM_THREADS; i++) //loop para criar threads
{
printf ("Main: criando thread %02ld\n", i) ;
status = pthread_create (&thread[i], NULL, threadBody, (void *) i) ;
if (status)
{
perror ("pthread_create") ;
exit (1) ;
}
}
pthread_exit (NULL) ;
}
Print do Terminal
Funcionamento do programa
O funcionamento do código é basicamente igual ao código do primeiro exercício,
porém no corpo da função executada pelas threads a da variável global inteira x é
incrementada em dois momentos: antes e depois de uma chamada da função sleep, que
faz a thread dormir por três segundos. Analisando os valores da variável conforme as
threads são chamadas, é possível perceber que não há garantia da ordem de execução
e encerramento devido à imprevisibilidade das decisões do kernel, ao passo que a
ordem criação das threads é previsível, devido ao fato que elas são criadas em ordem
crescente via chamadas pthread_create no código.
Compare a evolução da variável x neste programa com aquela que ocorreria
em um programa equivalente usando a chamada de sistema fork. Compare a evolução
da variável x neste programa com aquela que ocorreria em um programa equivalente
usando a chamada de sistema fork.
Thread independe do processo que está ocorrendo, ele sempre incrementa 1
sequencialmente. O fork não consegue fazer essa sequência de soma, ele ficaria
trocando valores, pois ele é dependente do processo.
Diagrama de tempo
Download