PThreads MO801/MC972
Idéia básica API para gerenciamento de threads Vários tutoriais disponíveis na internet Google: pthread Cobrirei apenas os tópicos mais básicos
Visão geral Sem Threads Com Threads
Características Threads co-existem num mesmo processo, compartilhando vários recursos, mas são escalonadas separadamente pelo sistema operacional Somente o mínimo necessário de recursos é replicado entre duas threads
Requisitos para execução independente Pilha Registradores Propriedades de escalonamento Sinais pendentes e bloqueados Dados específicos da thread
Uma thread… Faz parte de um processo e usa seus recursos Possui um fluxo de controle independente enquanto o processo a mantiver viva Morre se o processo pai morrer Duplica somente os recursos essenciais Pode compartilhar recursos com outras threads É barata, pois todos os recursos necessários são reservados na criação do processo pai
Como threads compartilham recursos… Alterações feitas por uma thread afetam as outras Ex.: Fechar um arquivo Dois ponteiros com o mesmo valor acessam o mesmo dado Leituras e escritas do mesmo endereço é possível É recomendado que se utilize algum mecanismo de sincronização
Como projetar programas com threads
PThread API Prefix Funcionality pthread_ Threads themselves and miscellaneous subroutines pthread_attr_ Thread attributes objects pthread_mutex_ Mutexes pthread_mutexattr_ Mutex attributes objects pthread_cond_ Condition variables pthread_cond_attr Condition attributes objects pthread_key_ Thread-specific data keys
Como programar Usar Compilar com a opção –lpthread #include “pthread.h” Compilar com a opção –lpthread gcc –lpthread pthread.c
Criando uma thread int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
pthread_create #include <stdio.h> #include <stdlib.h> #include <pthread.h> void *print_message_function( void *ptr ); main() { pthread_t thread1, thread2; char *message1 = "Thread 1“, *message2 = "Thread 2"; int iret1, iret2; iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1); iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2); pthread_join( thread1, NULL); pthread_join( thread2, NULL); printf("Thread 1 returns: %d\n",iret1); printf("Thread 2 returns: %d\n",iret2); exit(0); } void *print_message_function( void *ptr ) char *message; message = (char *) ptr; printf("%s \n", message);
Encerrando uma thread Além da alternativa de simplesmente encerrar a função, é possível também void pthread_exit(void *retval);
Mutex /* Note scope of variable and mutex are the same */ pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; int counter=0; /* Function C */ void functionC() { pthread_mutex_lock( &mutex1 ); counter++ pthread_mutex_unlock( &mutex1 ); }
Fontes de problemas Condição de corrida Thread safe code Deadlock Não assuma uma ordem específica para a execução das threads Um código pode funcionar muito bem em determinados momentos e gerar sérios problemas em outros Thread safe code Use bibliotecas que possuam chamadas “thread safe” Várias chamadas à mesma função devem ser permitidas Deadlock