This shows you the differences between two versions of the page.
app:laboratoare:04 [2022/11/01 07:50] rares.folea [Exerciții] |
app:laboratoare:04 [2024/10/29 02:44] (current) alexandru.bala [Variabile condiție] |
||
---|---|---|---|
Line 25: | Line 25: | ||
* ''attr'' - atributele unui thread (''NULL'' - atribute default) | * ''attr'' - atributele unui thread (''NULL'' - atribute default) | ||
* ''thread_function'' - funcția pe care să o execute thread-ul | * ''thread_function'' - funcția pe care să o execute thread-ul | ||
- | * ''arg'' - parametrul trimis la funcția executată de thread (dacă vrem să trimitem mai mulți parametri, îi împachetăm într-un struct | + | * ''arg'' - parametrul trimis la funcția executată de thread (dacă vrem să trimitem mai mulți parametri, îi împachetăm într-un struct) |
Exemplu de funcție pe care o execută un thread: | Exemplu de funcție pe care o execută un thread: | ||
Line 243: | Line 243: | ||
printf("After barrier - thread %d\n", index); | printf("After barrier - thread %d\n", index); | ||
- | pthread_exit(NULL); | + | pthread_exit(NULL); |
} | } | ||
Line 269: | Line 269: | ||
==== Semafor ==== | ==== Semafor ==== | ||
- | Un semafor este un element de sincronizare, care reprezintă o generalizare a mutex-ului. Semaforul are un contor care este incrementat la intrarea unui thread în zona de cod critică și care e decrementat când thread-ul respectiv iese din zona critică (contorul nu poate fi negativ în pthreads). | + | Un semafor este un element de sincronizare, care reprezintă o generalizare a mutex-ului. Semaforul are un contor care este decrementat la intrarea unui thread în zona de cod critică și care e incrementat când thread-ul respectiv iese din zona critică (contorul nu poate fi negativ în pthreads). |
Pentru a folosi semafoare în pthreads ne folosim de structura ''sem_t'', pentru care trebuie să includem biblioteca ''semaphore.h''. | Pentru a folosi semafoare în pthreads ne folosim de structura ''sem_t'', pentru care trebuie să includem biblioteca ''semaphore.h''. | ||
Line 280: | Line 280: | ||
* ''int sem_init(sem_t *sem, int pshared, unsigned int value);'' - inițiere semafor | * ''int sem_init(sem_t *sem, int pshared, unsigned int value);'' - inițiere semafor | ||
* ''int sem_destroy(sem_t *sem);'' - distrugere semafor | * ''int sem_destroy(sem_t *sem);'' - distrugere semafor | ||
- | * ''int sem_post(sem_t *sem);'' - acquire | + | * ''int sem_wait(sem_t *sem);'' - acquire |
- | * ''int sem_wait(sem_t *sem);'' - release | + | * ''int sem_post(sem_t *sem);'' - release |
Exemplu folosire - producer - consumer: | Exemplu folosire - producer - consumer: | ||
Line 325: | Line 325: | ||
printf ("Produs un element.\n"); | printf ("Produs un element.\n"); | ||
- | pthread_mutex_unlock (&mutex); | + | pthread_mutex_unlock (&mutex); |
my_pthread_sleep (rand () % 1000); | my_pthread_sleep (rand () % 1000); | ||
Line 364: | Line 364: | ||
srand (time (NULL)); | srand (time (NULL)); | ||
for (i = 0; i < NUM_THREADS; i++) { | for (i = 0; i < NUM_THREADS; i++) { | ||
- | type = rand () % 2; | + | type = i % 2; // ar funcționa și rand () % 2 în loc de i % 2? |
if (type == CONSUMER) { | if (type == CONSUMER) { | ||
- | pthread_create (&tid_v[i], NULL, consumer_func, NULL); | + | pthread_create (&tid_v[i], NULL, consumer_func, NULL); |
- | } else { | + | } else { |
pthread_create (&tid_v[i], NULL, producer_func, NULL); | pthread_create (&tid_v[i], NULL, producer_func, NULL); | ||
} | } | ||
- | } | + | } |
for (i = 0; i < NUM_THREADS; i++) { | for (i = 0; i < NUM_THREADS; i++) { | ||
pthread_join (tid_v[i], NULL); | pthread_join (tid_v[i], NULL); | ||
- | } | + | } |
- | pthread_mutex_destroy(&mutex); | + | pthread_mutex_destroy(&mutex); |
return 0; | return 0; | ||
Line 386: | Line 386: | ||
Variabilele condiție reprezintă o structură de sincronizare, care au asociat un mutex, și ele au un sistem de notificare a thread-urilor, astfel încât un thread să fie blocat până când apare o notificare de la alt thread. Pentru a putea folosi variabile condiție în pthreads ne folosim de structura ''pthread_cond_t''. | Variabilele condiție reprezintă o structură de sincronizare, care au asociat un mutex, și ele au un sistem de notificare a thread-urilor, astfel încât un thread să fie blocat până când apare o notificare de la alt thread. Pentru a putea folosi variabile condiție în pthreads ne folosim de structura ''pthread_cond_t''. | ||
- | Variabilele condiție sunt folosite pentru a bloca thread-ul curent (mutexul și semaforul blochează celelalte thread-uri). Acestea permit unui thread să se blocheze până când o condiție devine adevărată, moment când condiția este semnalată de thread că a devenit adevărată și thread-ul / thread-urile blocate de condiție își reiau activitatea o variabilă condiție va avea mereu un mutex pentru a avea race condition, care apare când un thread 0 se pregătește să aștepte la variabila condiție și un thread 1 semnalează condiția înainte ca thread-ul 0 să se blocheze | + | Variabilele condiție sunt folosite pentru a bloca thread-ul curent (mutexul și semaforul blochează celelalte thread-uri). Acestea permit unui thread să se blocheze până când o condiție devine adevărată, moment când condiția este semnalată de thread că a devenit adevărată și thread-ul / thread-urile blocate de condiție își reiau activitatea. O variabilă condiție va avea mereu un mutex pentru a avea race condition, care apare când un thread 0 se pregătește să aștepte la variabila condiție și un thread 1 semnalează condiția înainte ca thread-ul 0 să se blocheze. |
Funcții: | Funcții: | ||
Line 395: | Line 395: | ||
* ''int pthread_cond_signal(pthread_cond_t *cond);'' - deblocarea unui thread | * ''int pthread_cond_signal(pthread_cond_t *cond);'' - deblocarea unui thread | ||
* ''int pthread_cond_broadcast(pthread_cond_t *cond);'' - deblocarea tuturor thread-urilor blocate | * ''int pthread_cond_broadcast(pthread_cond_t *cond);'' - deblocarea tuturor thread-urilor blocate | ||
- | * | ||
Exemplu folosire - producer - consumer: | Exemplu folosire - producer - consumer: | ||
<spoiler Click pentru exemplu> | <spoiler Click pentru exemplu> | ||
Line 479: | Line 478: | ||
srand (time (NULL)); | srand (time (NULL)); | ||
for (i = 0; i < NUM_THREADS; i++) { | for (i = 0; i < NUM_THREADS; i++) { | ||
- | type = rand () % 2; | + | type = i % 2; // ar funcționa și rand () % 2 în loc de i % 2? |
if (type == CONSUMER) { | if (type == CONSUMER) { | ||
pthread_create (&tid_v[i], NULL, consumer_func, NULL); | pthread_create (&tid_v[i], NULL, consumer_func, NULL); |