Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rdemeter
GitHub Repository: rdemeter/so
Path: blob/master/lab8/cond_var.c
221 views
1
#include <stdio.h>
2
#include <pthread.h>
3
4
#define NUM_THREADS 5
5
// implementarea unei bariere *nereentrante* cu variabile de conditie
6
struct my_barrier_t {
7
// mutex folosit pentru a serializa accesele la datele interne ale barierei
8
pthread_mutex_t lock;
9
// variabila de conditie pe care se astepta sosirea tuturor firelor de executie
10
pthread_cond_t cond;
11
// numar de fire de executie care trebuie sa mai vina pentru a elibera bariera
12
int nr_still_to_come;
13
};
14
15
struct my_barrier_t bar;
16
17
void my_barrier_init(struct my_barrier_t * bar, int nr_still_to_come)
18
{
19
pthread_mutex_init(&bar->lock, NULL);
20
pthread_cond_init(&bar->cond, NULL);
21
// cate fire de executie sunt asteptate la bariera.
22
bar->nr_still_to_come = nr_still_to_come;
23
}
24
25
void my_barrier_destroy(struct my_barrier_t * bar)
26
{
27
pthread_cond_destroy(&bar->cond);
28
pthread_mutex_destroy(&bar->lock);
29
}
30
31
void *thread_routine(void *arg)
32
{
33
int thd_id = (int) arg;
34
// inainte de a lucra cu datele interne ale barierei trebuie sa preluam mutexul
35
pthread_mutex_lock(&bar.lock);
36
printf("thd %d: before the barrier\n", thd_id);
37
// suntem ultimul fir de executie care a sosit la bariera?
38
int is_last_to_arrive = (bar.nr_still_to_come == 1);
39
// decrementam numarul de fire de executie asteptate la bariera
40
bar.nr_still_to_come --;
41
// cat timp mai sunt threaduri care nu au ajuns la bariera, asteptam.
42
while (bar.nr_still_to_come != 0)
43
// lockul se elibereaza automat inainte de a incepe asteptarea
44
pthread_cond_wait(&bar.cond, &bar.lock);
45
46
// ultimul thread ajuns la bariera va semnaliza celelalte threaduri
47
if (is_last_to_arrive) {
48
printf("let the flood in\n");
49
pthread_cond_broadcast(&bar.cond);
50
}
51
printf("thd %d: after the barrier\n", thd_id);
52
53
// la iesirea din functia de asteptare se preia automat mutexul, trebuie eliberat.
54
pthread_mutex_unlock(&bar.lock);
55
return NULL;
56
}
57
58
int main(void) {
59
int i;
60
pthread_t tids[NUM_THREADS];
61
my_barrier_init(&bar, NUM_THREADS);
62
63
for (i = 0; i < NUM_THREADS; i++)
64
pthread_create(&tids[i], NULL, thread_routine, (void *) i);
65
66
for (i = 0; i < NUM_THREADS; i++)
67
pthread_join(tids[i], NULL);
68
69
my_barrier_destroy(&bar);
70
return 0;
71
}
72
73