Você está na página 1de 4

Material de apoio de Pthread

1) Como compilar e executar um programa em pthread?


Compilar: g++ -pthread arquivo.cpp -o arquivo.o
Executar: ./a.out
2) Onde encontrar código fonte da biblioteca pthread:
/usr/include/pthread.h
3) Criação de threads - pthread_create cria uma nova thread passando
a rotina que será executada e argumentos para essa rotina
int​ ​pthread_create​(
pthread_t ​*​thread​,​ ​// armazena id da thread (pthread_t é unsigned
long int)
​const​ pthread_attr_t ​*​attr​,​ ​// armazena atributos para thread
(pthread_attr_t é registro com vetor de char e long int)
​void​ ​*(*​start_routine​)​ ​(​void​ ​*),​ ​// rotina que será executada
​void​ ​*​arg ​// argumentos para a rotina
)​;

4) Join - A thread que chama pthread_join espera a terminação da thread com id informado.
O status de saída da thread é armazenado em retval.
​int​ pthread_join​(
pthread_t ​thread​, ​// id da thread
void​ **retval ​// status de retorno
);
5) Exit - termina a execução da thread que chamou pthread_exit
void​ pthread_exit​(
void​ ​*​retval ​// status de retorno
)​;

Exemplo:
#include​ ​<​pthread.h​>
#include​ ​<​iostream​>
using​ ​namespace​ std;

void​ *PrintHello(​void​ *threadid)


{
​long​ tid;
tid = (​long​)threadid;
cout << ​"Sou a thread "​ << tid << endl;
pthread_exit(NULL);
}

int​ main (​int​ argc, ​char​ *argv[])


{
pthread_t threads;
​int​ rc;
​long​ t=​1​;
// após chamar pthread_create haverá a thread principal e uma nova
thread no sistema
rc = pthread_create(&threads, NULL, PrintHello, (​void​ *)t);
// ao passar NULL como argumento, são usados os atributos padrão para
thread
​if​ (rc){
cout << ​"ERROR; return code from pthread_create() is "​ << rc <<
endl;
exit(-​1​);
}
pthread_exit(NULL);
return 0;
}

Saída na tela:

6) Para criar um número maior de threads que executam a mesma rotina é necessário utilizar
uma estrutura de repetição.
// neste for serão criadas NUM_THREADS executando a mesma tarefa
(PrintHello)
for ​(t=​0​; t<NUM_THREADS; t++){
rc = pthread_create(&threads[t], NULL, PrintHello, (​void​*)t);
}

7) Para passar mais argumentos para a rotina pode-se usar vetor ou registro.
--> Utilizando vetor
#include ​<​pthread.h​>
#include ​<​iostream​>
#include ​<​sys/time.h​>
#define NUM_THREADS 4

using​ ​namespace​ ​std​;


void​ ​*​PrintHello​(​void​ ​*​threadid​)
{
​struct​ ​timeval​ tv​;
​unsigned​ ​long​ ​*​tid ​=​ ​(​unsigned​ ​long​*)​threadid​;
​unsigned​ ​long​ id ​=​ tid​[​0​]​;
gettimeofday​(&​tv​,​ ​NULL​)​;
​cout​ ​<<​tv​.​tv_usec​<<​"​ ​"​<<​ tv​.​tv_usec ​-​ id ​<<​ ​endl​;
pthread_exit​(​NULL​)​;
}

int​ ​main​ ​(​int​ argc​,​ ​char​ ​*​argv​[])


{
pthread_t threads​[​NUM_THREADS​]​;
​int​ rc​;
​timeval​ tv​;
gettimeofday​(&​tv​,​ ​NULL​)​;
​cout​ ​<<​"​Tempo inicial: ​"​ ​<<​ tv​.​tv_usec ​<<​ ​endl​;
// Vetor usado para passar os argumentos para função print
​unsigned​ ​long​ t​[​2​]​;
t​[​0​]=​ tv​.​tv_usec ​;
t​[​1​]​ ​=​ NUM_THREADS​;
​cout​ ​<<​ ​"​Tempo na função | ​"​ ​<<​ ​"​ Diferença: final - inicial​"​ ​<<
endl​;
​for​ ​(​ ​int​ j​=​1​;​ j​<​NUM_THREADS​;​ j​++)​{
rc ​=​ pthread_create​(&​threads​[​j​],​ ​NULL​,​ PrintHello​,​ ​(​void​ ​*)​t​)​;
​if​ ​(​rc​)​{
​cout​ ​<<​ ​"​ERRO: código de retorno de pthread_create(): ​"​ ​<<​ rc
<<​ ​endl​;
​exit​(-​1​)​;
​}
​}
pthread_exit​(​NULL​)​;
}

--> Utilizando registro


#include ​<​iostream​>
#include ​<​pthread.h​>
#define NUMTHREADS 4
using​ ​namespace​ ​std​;
struct​ threadArgs ​{​ ​// registro criado para armazenar os parâmetros
​unsigned​ ​long​ id​;
​unsigned​ ​long​ numThreads​;
​int​ code​;
};

void​*​ childGreetings​(​void​ ​*​ buf​)​ ​{


threadArgs ​*​args ​=​ ​(​threadArgs​*)​ buf​;
​unsigned​ ​long​ childID ​=​ args​->​id​;
​unsigned​ ​long​ numThreads ​=​ args​->​numThreads​;
​//Id da thread | Numero de threads | codigo
​cout​ ​<<​ childID ​<<​ ​"​ : ​"​ ​<<​ numThreads ​<<​ ​"​ : ​"​ ​<<​ args​->​code ​<<​ ​endl​;
​return​ ​NULL​;
}
int​ ​main​(​int​ argc​,​ ​char​**​ argv​)​ ​{
pthread_t children​[​NUMTHREADS​]​;
​int​ id_thread ​=​ ​0​;
​struct​ threadArgs ​*​args​;

​for​ ​(​id_thread ​=​ ​0​;​ id_thread ​<​ NUMTHREADS​;​ id_thread​++)​ ​{


args ​=​ ​(​threadArgs​*)​ ​malloc​(​ ​sizeof​(​ ​struct​ threadArgs ​)​ ​)​;​ ​// aloca estrutura para cada
thread
​(*​args​).​id ​=(​unsigned​ ​long​)​id_thread​;;
​(*​args​).​numThreads ​=​ NUMTHREADS​;
​(*​args​).​code ​=​ id_thread​*​100​;
pthread_create​(​ ​&(​children​[​id_thread​]),​ ​// armazena identificador da thread
​NULL​,​ ​// atributos das threads
childGreetings​,​ ​// tarefa a ser executada pela thread
​(​void​*)​ args ​)​;​ ​// argumentos para childGreetings
​}
​cout​ ​<<​ ​"​Thread principal ​"​ ​<<​ ​endl​;
​for​ ​(​id_thread ​=​ ​0​;​ id_thread ​<​ NUMTHREADS​;​ id_thread​++)​ ​{
pthread_join​(​ children​[​id_thread​],​ ​NULL​ ​)​;
​}
​return​ ​0​;
}

Você também pode gostar