Esta aula tem por objetivo introduzir a sincronização entre threads através da utilização de semáforos e locks. Para tal, deverá implementar pequenos programas que respondam aos requisitos de cada uma das tarefas que se seguem. Para obter mais informação sobre as funções de sistema referidas, consulte as man-pages respetivas.
Thr1: 1 Thr2: 2 Thr1: 3 ... Thr2: 18 Thr1: 19 Thr2: 20A thread Thr1 deve imprimir as linhas ímpares e a thread Thr2 as linhas pares, até atingirem um determinado valor (20 no exemplo). Cada thread deverá ter associado um semáforo (neste caso será mais conveniente utilizar semáforos unnamed). Para indicar à outra thread a sua vez de imprimir, a thread deverá sinalizar o semáforo associado a essa thread. Deverá depois aguardar (no seu semáforo) que a outra thread lhe passe novamente a vez de imprimir.
pthread_create()
, pthread_join()
,
pthread_exit()
, sem_init()
,
sem_wait()
, sem_post()
e
sem_destroy()
.
./a.out vector_size threadsem que
vector_size
é o tamanho dos vetores
e threads
é o número de threads envolvidas na
computação (este argumento será utilizado mais tarde, no código
abaixo é simplesmente ignorado).
#include <stdio.h> #include <stdlib.h> long long *create_vector1(int); long long *create_vector2(int); void do_work(void); void produto_interno(int, int); int threads, vector_size; long long prod_int, *vector_a, *vector_b; int main(int argc, char *argv[]) { vector_size = atoi(argv[1]); threads = atoi(argv[2]); vector_a = create_vector1(vector_size); vector_b = create_vector2(vector_size); do_work(); return EXIT_SUCCESS; } long long *create_vector1(int size) { int i; long long *vector; vector = (long long *) malloc(size * sizeof(long long)); for (i = 0; i < size; i++) vector[i] = i; return vector; } long long *create_vector2(int size) { int i; long long *vector; vector = (long long *) malloc(size * sizeof(long long)); for (i = 0; i < size; i++) vector[i] = size-i-1; return vector; } void do_work(void) { prod_int = 0; produto_interno(0, vector_size); printf("Produto Interno = %lld\n", prod_int); return; } void produto_interno(int start, int end) { int i; for (i = start; i < end; i++) prod_int += vector_a[i] * vector_b[i]; return; } |
threads
. Por exemplo, se indicarmos T
threads e se os vetores tiverem tamanho N, então cada thread
poderá calcular N/T componentes do produto interno e ir somando o
resultado na variável global prod_int
. Para tal
deverá fazer o lançamento das threads, calcular as componentes do
produto interno que cada deverá calcular e sincronizar a
atualização da variável prod_int
entre todas as
threads. No final, compare os valores obtidos para o produto
interno com os da alínea anterior.pthread_create()
, pthread_join()
,
pthread_exit()
, pthread_mutex_init()
,
pthread_mutex_lock()
e pthread_mutex_unlock()
.