Você está na página 1de 35

Threads

threads em Linux Taisy Weber

Ambiente UNIX
4Processos:
reviso de conceitos bsicos processos no SO UNIX

3programao
criao (exec, fork, etc), sincronizao (wait), eliminao, processos zombie

signals

3conceito de threads, threads em Linux


Mitchell, cap 4 Matthew & Stones, cap 11
Taisy Weber

Operating System Concepts Silberschatz & Galvin, 1998


2

Threads em Linux
4conceito de threads 4Posix threads 4create, exit and join 4simultaneidade e concorrncia 4seo crtica 4semforos, mutex
no contexto de threads

Taisy Weber

Threads
4processo
definido pelo recursos usados e espao de memria onde est executando

F
4thread

pode ser interessante partilhar recursos concorrentemente semelhante a um processo filho com novo IP mas executando no mesmo espao de endereamento do pai
4

Taisy Weber

Thread
processo leve (lightweigth process)

thread

unidade bsica de uso da CPU um IP, um conjunto de registradores, e uma pilha

compartilha recursos com threads da mesma task conjunto de threads uma task com apenas uma thread igual a um processo convencional
5

recursos compartilhados rea de cdigo, rea de dados, arquivos abertos, ...

Taisy Weber

Thread
4principais vantagens frente a processos: 3maior facilidade na criao 3maior velocidade de troca de contexto entre threads da mesma task
ainda necessrio troca de registradores

no necessrio troca de pginas de memria


CUIDADO: multithread pode acarretar problemas de concorrncia
Taisy Weber

Task & threads


threads

mltiplas linhas de controle associadas a recursos comuns

instruction pointer segmento de cdigo

segmento de dados

task
mltiplas threads em uma task
Taisy Weber

Threads semelhantes a processos


4operam de forma semelhante a processos 3estados:
pronto, bloqueado, executando, terminado

3apenas uma thread de cada vez em execuo na CPU 3uma thread executa seqencialmente 3uma thread pode criar threads filhas
Taisy Weber

Threads diferentes de processos


4mas so diferentes de processos
se thread for suportada pelo SO

3quando uma thread bloqueia, outra thread da mesma task pode ser executada
um processo fica inteiramente bloqueado

3threads no so independentes umas das outras


uma thread pode invadir o espao de outra thread invalidando-a

3threads no so protegidas uma das outras


Taisy Weber

Implementao de threads
4ou suportadas pelo kernel
atravs de system calls como os processos

4ou suportadas por chamadas de rotinas em

uma biblioteca no nvel do usurio


threads de usurio so rpidas na troca de contexto entre si uma chamada ao SO faz todo o processo esperar (o SO ignora threads do usurio e s reconhece processos) Linux suporta threads de usurio atravs de package system call clone do Linux
10

4ou ambas
Taisy Weber

Processos e threads no Linux


4Linux trata tudo como task 3threads so casos particulares de processos 3internamente processos e threads so tratados da mesma forma
a diferena aparece apenas na hora da criao (por syscall): fork cria novo processo clone cria thread

thread: processo com identidade prpria, com prprio contexto de escalonamento, mas que compartilha a estrutura de dados com seu pai

ambas system calls chamam a rotina do-fork do kernel


Taisy Weber

11

Suporte a threads
4padro POSIX 3_POSIX_VERSION 4teste de suporte
no livro texto h um exemplo de programa para verificao do suporte a threads Matthew & Stones, cap 11 fonte: thread1.c aconselhvel testar suporte a threads no seu sistema antes de iniciar com os exerccios
Taisy Weber

procurar nos arquivos header

valor 199506L ou maior

12

Posix threads
4biblioteca para threads Posix 3lpthread linkar usando -lpthread 4designao 3nomes de chamadas de funo iniciam com pthread incluir arquivo pthread.h
3nome do header file: pthread.h

Taisy Weber

13

Cdigo reentrante
3pode ser chamado mais de uma vez e ainda funcionar corretamente
vale para invocaes aninhadas vale para threads

condio: usar apenas variveis locais


assim a execuo de cada chamada vai possuir sua cpia particular de variveis

3macro _REENTRANT
usar antes de qualquer #include em programas multithread informa ao compilador que necessrio
gerar cdigo reentrante
Taisy Weber

14

create, exit and join


thread create thread criadora join thread

rotina da thread

exit

thread criada executa

uma thread criada pela funo pthread_create, que indica qual a rotina deve ser executada pela nova thread
Taisy Weber

15

create
#include <pthread.h> int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine) (void*), void *arg);

identificador da thread
pthread_t *thread

conjunto de atributos da thread


pthread_attr_t *attr void *(*start_routine) (void*) void *arg

funo que a thread executa aps sua criao


passa o endereo de uma funo tomando um ponteiro para void como parmetro e retornando um ponteiro para void

argumentos passados a start_routine

Taisy Weber

16

exit & join


#include <pthread.h>

semelhante a exit para processos

void pthread_exit(void *retval);

retorna um ponteiro para um objeto (jamais retornar pointer para uma varivel local a thread, pois essas variveis desaparecem aps exit)
#include <pthread.h>

semelhante a wait para coleta de processos filhos

int pthread_join(pthread_t th, void **pthread_return);

pthread_t th

identificador da thread que se deseja esperar ponteiro para um ponteiro com o valor de retorno da thread
17

void **pthread_return

Taisy Weber

Primeiro programa com threads


int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, void *thread_function(void *arg); thread_function, (void *)message); if (res != 0) { char message[] = "Hello World"; perror("Thread creation failed"); exit(EXIT_FAILURE); } printf("Waiting for thread to cria uma thread extra, mostra finish...\n"); res = pthread_join(a_thread, compartilhamento de variveis e &thread_result); captura valor de retorno da thread if (res != 0) { perror("Thread join failed"); extra exit(EXIT_FAILURE); message varivel global } printf("Thread joined, it returned %s\n", (char *)thread_result); fonte: thread2.c printf("Message is now %s\n", message); exit(EXIT_SUCCESS); } Taisy Weber 18 #include #include #include #include <stdio.h> <unistd.h> <stdlib.h> <pthread.h>

Continua: prim. prog.


void *thread_function(void *arg) { printf("thread_function is running. Argument was %s\n", (char *)arg); sleep(3); strcpy(message, "Bye!"); pthread_exit("Thank you for the CPU time"); }

start_routine: thread_function strcpy - string copy

$ cc -D_REENTRANT thread2.c -o thread2 -lpthread executar e determinar a sada


lab
Taisy Weber

19

Simultaneidade e concorrncia
em computadores monoprocessados, threads no executam simultaneamente mas concorrentemente

3tudo, exceto variveis locais, partilhado entre as threads de uma tarefa


potencial para gerar conflitos entre threads
vrios processos acessam concorrentemente uma varivel comum e o resultado depende da ordem dos acessos

3evitando conflitos
garantir que apenas um processo (ou thread) de cada vez manipule uma varivel compartilhada
usar semforos e mutexes para sincronizar threads
Taisy Weber

20

Seo crtica
4o que ?
acesso a recursos compartilhados

trecho de cdigo no qual um processo pode estar alterando variveis comuns, escrevendo uma tabela, escrevendo um arquivo, ...

4para evitar conflitos

excluso mtua no tempo

quando um processo executa em sua seo crtica, nenhum outro processo pode executar na sua seo crtica
cada regio crtica pode ser diferente

Taisy Weber

21

Soluo para seo crtica


entry section

3cada processo pede permisso para entrar em sua seo crtica


exit section

3a seo crtica seguida por uma seo de sada


entry section critical section exit section remainder section
Taisy Weber

se nenhum outro processo pode executar na regio crtica, variveis compartilhadas so preservadas
22

Requisitos para SC
4excluso mtua 4progresso
quando um processo executa em sua SC, nenhum dos outros processos pode executar na sua SC

se no existem processos na SC e se existem procs. que querem entrar na SC, ento apenas esses procs. podem participar da deciso de quem ser o prximo e a deciso no pode ser postergada infinitamente

4espera limitada
existe um nmero limitado de vezes que um outro processo pode entrar sua SC depois que um processo que pediu permisso a receba
Taisy Weber

23

Semforo
fora a inicializao

3S uma varivel inteira que acessada apenas por duas operaes atmicas: P e V
wait e signal so sees crticas

semforo

P V

wait(S): while S 0 do no-op; S:= S - 1; signal(S): S:= S + 1;

teste do semforo e sua alterao uma operao atmica


Taisy Weber

se um processo altera o valor do semforo, nenhum outro processo pode simultaneamente modificar o mesmo semforo

24

Seo crtica com mutex


mutual exclusion

4seo crtica com n processos (ou threads)


implementao de mutex como semforo n processos compartilham o semforo mutex com valor inicial 1

repeat wait(mutex); critical section signal(mutex); remainder section until ...


Taisy Weber

lock while mutex 0 do no-op; mutex := mutex - 1; unlock mutex := mutex +1;
25

Semforo com busy waiting


4problemas: while condition do no-op 3solues com espera em lao de execuo
queda de desempenho: processos ocupam CPU sem executar trabalho til

3semforo implementado com busy waiting chamado spinlock


til em multiprocessadores, evita chaveamento de contexto
Taisy Weber

26

Semforo sem busy waiting


4wait
se o semforo no positivo, o processo bloqueia

processo vai para fila de espera associada ao semforo, estado do processo = wait

4signal

coloca o outro processo em ready

um processo executando signal retira um outro processo da fila de espera associada ao semforo como mutex um caso especial de semforo, a mesma implementao vale para lock e unlock
Taisy Weber

27

Deadlock com semforos


P0 wait(S) wait(Q) . . signal(S) signal(Q) executado na fila P1 wait(Q) wait(S) . . signal(Q) signal(S)

2 ou mais processos esperam indefinidamente por um evento causado apenas por outro processo tambm bloqueado
Taisy Weber

28

Sincronizao de threads com mutexes


#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_destroy(pthread_mutex_t *mutex);

atributos para mutex (mutexattr) podem ser alterados de forma a evitar deadlocks aqui sero usados atributos padres (passando null no argumento)
Taisy Weber

29

Exemplo usando mutex: parte 1


fonte thread5.c
#include #include #include #include #include <stdio.h> <unistd.h> <stdlib.h> <pthread.h> <semaphore.h>

void *thread_function(void *arg); pthread_mutex_t work_mutex; /* protege work_area e time_to_exit */

#define WORK_SIZE 1024 char work_area[WORK_SIZE]; int time_to_exit = 0;

declara mutex e as variveis comuns mutex protege essas variveis

determinar a linha de comando para compilao executar e determinar a sada


lab
Taisy Weber

30

Exemplo usando mutex: parte 2


main ...
int main() { int res; pthread_t a_thread; void *thread_result;

inicializa mutex work_mutex

res = pthread_mutex_init(&work_mutex, NULL); if (res != 0) { perror("Mutex initialization failed"); exit(EXIT_FAILURE); }

cria thread a_thread

res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); }

errno no usado por essas funes pthread, res deve ser testado
Taisy Weber

31

Exemplo usando mutex: parte 3


...main ...
pthread_mutex_lock(&work_mutex); printf("Input some text. Enter 'end' to finish\n");

'end' faz a outra thread ligar time_to_exit


while(!time_to_exit) { fgets(work_area, WORK_SIZE, stdin); pthread_mutex_unlock(&work_mutex); while(1) { pthread_mutex_lock(&work_mutex); if (work_area[0] != '\0') { pthread_mutex_unlock(&work_mutex); sleep(1); } else { break; } } } pthread_mutex_unlock(&work_mutex);

verifica se a outra thread consumiu o string lido testando varivel compartilhada dentro de uma regio crtica

essa thread l o string para a outra thread processar


Taisy Weber

32

Exemplo usando mutex: parte 4


... main
printf("\nWaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } espera pela printf("Thread joined\n"); pthread_mutex_destroy(&work_mutex); terminar exit(EXIT_SUCCESS); }

outra thread

destroi mutex

Taisy Weber

33

Exemplo usando mutex: parte 5


void *thread_function(void *arg) { sleep(1);

rotina da thread
primeira entrada na regio crtica

pthread_mutex_lock(&work_mutex); while(strncmp("end", work_area, 3) != 0) { printf("You input %d characters\n", strlen(work_area) -1); work_area[0] = '\0'; pthread_mutex_unlock(&work_mutex); sleep(1); strncmp compara strings pthread_mutex_lock(&work_mutex); strlen comprimento do string while (work_area[0] == '\0' ) { pthread_mutex_unlock(&work_mutex); sleep(1); pthread_mutex_lock(&work_mutex); } } time_to_exit = 1; work_area[0] = '\0'; pthread_mutex_unlock(&work_mutex); ltima sada da regio crtica pthread_exit(0); }

coloca null no string para indicar que processou string


Taisy Weber

34

Fim
3existem mais detalhes sobre threads 3fogem ao escopo da nossa disciplina
olhar livros textos olhar man sobre threads

Taisy Weber

35