Professional Documents
Culture Documents
Todo o material aqui disponvel pode, posteriormente, ser utili ado so!re os termos da" Atribuio Creative Commons License: so no comercial - !erman"ncia da Licena
#tt$:%%creativecommons.or&%licenses%by-nc-sa%'.(%
2 / 34
#otivao
$esempenho
Conseguir redu ir o tempo de e%ecuo dos programas em m&quinas multiprocessadas
#odelagem
$escrever o comportamento natural de algumas aplica'es (opera'es ()*, ocorr+ncia assncrona de eventos, tare,as independentes, etc-)
3 / 34
4 / 34
5 / 34
6 / 34
8 / 34
9 / 34
10 / 34
Processos vs Threads
5onte" https"))computing-llnl-gov)tutorials)pthreads)
11 / 34
Processos
for)*+
Para criar processos no 4inu%, deve6se usar a chamada de sistema for)*+ fork() ,a com que o processo atual se7a dividido em dois novos processos processo pai e processo filho Todas as p&ginas de mem1ria do processo original so duplicadas em uma chamada ao fork(), assim am!os, pai e ,ilho, tem acesso a todas as in,orma'es-
12 / 34
Processos
for)*+
8alor de retorno"
.o pai" Processo ($ (P($) do ,ilho .o ,ilho" 9 ( ero)
3e o ,or:() ,alhar por algum motivo (,alta de mem1ria, muitos processos, etc-), ele no cria um novo processo, e retorna 61-
13 / 34
Processos
for)*+ , e-em$lo
#include<stdio.h> #include<unistd.h> #include <sys/wait.h> int main() { pid_t pid; pid = fork(); if (pid<0) { printf("Erro ao criar novo processo\n"); return 1; } else if (pid == 0) { printf("Filho... PID=%d\n", getpid()); } else { printf("Pai... PID=%d\n", getpid()); wait(NULL); } printf("%d - encerrando...\n", getpid()); return 0; } Italo Valcy Programao em C
14 / 34
Processos
for)*+
15 / 34
P*3(= Threads
.orma internacional (;;; P*3(= 199>-1 C Threads P*3(= podem implementar threads em nvel de usu&rio, em nvel de :ernel ou misto * programa em C deve conter" #include <pthread.h> ; para compilar, / necess&rio incluir a opo -pthread gcc -pthread programa.c
16 / 34
P*3(= Threads
.-em$lo
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5
void *PrintHello(void *arg) { int *tid = (int *)arg; printf("Hello World! It's me, thread #%d!\n", *tid); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int thread_id[NUM_THREADS]; int rc, t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %d\n", t); thread_id[t] = t; rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_id[t]); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Last thing that main() should do */ pthread_exit(NULL); }
17 / 34
P*3(= Threads
.-em$lo , $oss/vel sa/da
~$ gcc -pthread -o pthread-hello pthread-hello.c ~$ ./pthread-hello In main: creating thread 0 In main: creating thread 1 Hello World! It's me, thread #0! Hello World! It's me, thread #1! In main: creating thread 2 In main: creating thread 3 Hello World! It's me, thread #2! Hello World! It's me, thread #3! In main: creating thread 4 Hello World! It's me, thread #4!
18 / 34
19 / 34
;strutura de dados para arma enar in,orma'es so!re as threads- Para uso interno do pthread-h
2sada na criao, no 7oin, na ,inali ao, etc
;%emplo"
#include <pthread.h> #define NUM_THREADS 5 pthread_t threads[NUM_THREADS]; ...
20 / 34
@etorna 9 ( ero) se a criao tiver sucessovoid *myfunc(void *arg) { ... return (void *)result; } int main() { pthread_t onethread; int s = pthread_create(&onethread, NULL, &myfunc, NULL); }
21 / 34
22 / 34
;m sucesso, retorna 9B
... s = pthread_join(onethread, &res); ...
23 / 34
5inali a uma thread e retorna algum valor atrav/s de retval (pode6se o!t+6lo atrav/s de pthread?7oin)
... pthread_exit(&result); ...
24 / 34
;%erccio
5a er um programa que rece!e diversos ar&umentos de linha de comando e cria uma thread para imprimir cada argumento na sada padro-
25 / 34
;%erccio
$t#read-$rint-ar&s.c *2%3+
#include <stdio.h> #include <stdlib.h> #include <pthread.h> typedef struct mythread_args { int id; char *arg_string; } mythread_args_t; void *mythread_handler(void *arg) { mythread_args_t *myarg = (mythread_args_t *)arg; printf("Thread #%d - arg: %s\n", myarg->id, myarg->arg_string); }
26 / 34
;%erccio
$t#read-$rint-ar&s.c *3%3+
int main(int argc, char **argv) { pthread_t *threads; mythread_args_t *thread_args; int i, s; if (argc <= 1) { printf("%s <ARG1> [<ARG2> ...]\n", argv[0]); } argc--; threads = (pthread_t *)malloc(sizeof(pthread_t)*argc); thread_args = (mythread_args_t *)malloc(sizeof(mythread_args_t)*argc); for(i=0; i < argc; i++) { thread_args[i].id = i; thread_args[i].arg_string = argv[i+1]; printf("MAIN - Criando thread #%d\n", i); s = pthread_create(&threads[i], NULL, &mythread_handler, &thread_args[i]); if (s!=0) { printf(" -> Erro ao criar thread!\n"); exit(1); } } for(i=0; i < argc; i++) { s = pthread_join(threads[i], NULL); if (s!=0) { printf("Error na thread %d!\n", i); exit(1); } } return 0; }
27 / 34
P*3(= Threads
.-em$lo 3
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS int saldo = 1000; void *atualizaSaldo(void *arg) { int *tid = (int *)arg; int meu_saldo = saldo; int novo_saldo = meu_saldo + (*tid + 1)*100; printf("Thread #%d - Novo saldo: %d\n", *tid, novo_saldo); saldo = novo_saldo; pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int thread_id[NUM_THREADS]; int rc, i; for(i=0; i<NUM_THREADS; i++){ thread_id[i] = i; rc = pthread_create(&threads[i], NULL, &atualizaSaldo, (void *)&thread_id[i]); if (rc) exit(-1); } for(i=0; i < NUM_THREADS; i++) pthread_join(threads[i], NULL); printf("Saldo final: %d\n", saldo); return 0; } 5
28 / 34
P*3(= Threads
.-em$lo 3 , ordem de e-ecuo
29 / 34
#ecanismos de sincroni ao
;%cluso m0tua
2ma thread est& e%ecutando so inha um determinado c1digo, enquanto as outras esperam para poder e%ecutar
3esso crtica
Parte do programa que deve ser e%ecutada por somente uma thread de cada ve (em e%cluso m0tua)
30 / 34
#ecanismos de sincroni ao
3em&,oros ) #ute% #onitores Conditions Trocas de mensagem
31 / 34
#ute%
.-em$lo
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5
int saldo = 1000; pthread_mutex_t saldo_mutex; void *atualizaSaldo(void *arg) { int *tid = (int *)arg; pthread_mutex_lock(&saldo_mutex); int meu_saldo = saldo; int novo_saldo = meu_saldo + (*tid + 1)*100; printf("Thread #%d - Novo saldo: %d\n", *tid, novo_saldo); saldo = novo_saldo; pthread_mutex_unlock(&saldo_mutex); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int thread_id[NUM_THREADS]; int rc, i; pthread_mutex_init(&saldo_mutex, NULL); for(i=0; i<NUM_THREADS; i++){ thread_id[i] = i; rc = pthread_create(&threads[i], NULL, &atualizaSaldo, (void *)&thread_id[i]); if (rc) exit(-1); } for(i=0; i < NUM_THREADS; i++) pthread_join(threads[i], NULL); printf("Saldo final: %d\n", saldo); return 0; }
32 / 34
@e,er+ncia
https"))computing-llnl-gov)tutorials)pthreads)
33 / 34
;%erccio
#ultiplicao de matri es de ,orma paralela#ultiplicao de matri " A-DEC * calculo de um elemento da #atri C, envolve a multiplicao duma linha de #atri % A com a coluna da #atri D
a b e c d g
a. f + b.h c. f + d .h
.-er(4" 5a er um programa que rece!e duas matri es de tamanho vari&vel (#%P e P%F) como entrada e calcula a multiplicao entre elas em . threads di,erentes (a quantidade de threads tam!/m ser& in,ormada como entrada)
Italo Valcy Programao em C
34 / 34