pthread_cond_init(3) Library Functions Manual pthread_cond_init(3) NUME pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait, pthread_cond_destroy - operaii asupra condiiilor SINOPSIS #include pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); int pthread_cond_destroy(pthread_cond_t *cond); DESCRIERE O condiie (prescurtare de la ,,variabila de condiie") este un mecanism de sincronizare care permite firelor de execuie sa suspende execuia i sa cedeze procesoarele pana cand este satisfacuta o anumita condiie (un predicat) privind datele partajate. Operaiile de baza ale condiiilor sunt: semnalizarea condiiei (cand predicatul devine adevarat) i ateptarea condiiei, suspendand execuia firului pana cand un alt fir semnalizeaza condiia. O variabila de condiie trebuie sa fie intotdeauna asociata cu un mutex, pentru a evita condiia de ,,competiie pentru obinerea de date" in care un fir se pregatete sa atepte pe o variabila de condiie i un alt fir semnalizeaza condiia chiar inainte ca primul fir sa atepte efectiv pe ea. pthread_cond_init iniializeaza variabila de condiie cond, utilizand atributele de condiie specificate in cond_attr sau atributele implicite daca cond_attr este NULL. Implementarea ,,LinuxThreads" nu accepta atribute pentru condiii, prin urmare parametrul cond_attr este de fapt ignorat. Variabilele de tip pthread_cond_t pot fi, de asemenea, iniializate static, utilizand constanta PTHREAD_COND_INITIALIZER. pthread_cond_signal repornete unul dintre firele care ateapta variabila de condiie cond. In cazul in care niciun fir de execuie nu ateapta pe cond, nu se intampla nimic. In cazul in care mai multe fire ateapta pe cond, se repornete exact unul dintre ele, dar nu se specifica care. pthread_cond_broadcast repornete toate firele care ateapta variabila de condiie cond. Nu se intampla nimic daca niciun fir de execuie nu ateapta pe cond. pthread_cond_wait deblocheaza atomic mutex (conform pthread_unlock_mutex) i ateapta ca variabila de condiie cond sa fie semnalata. Execuia firului este suspendata i nu consuma timp de procesare pana cand variabila de condiie este semnalata. mutex trebuie sa fie blocata de firul apelant la intrarea in pthread_cond_wait. Inainte de a reveni la firul apelant, pthread_cond_wait recupereaza mutex (conform pthread_lock_mutex). Deblocarea mutex-ului i suspendarea pe variabila de condiie se face atomic. Astfel, daca toate firele achiziioneaza intotdeauna mutex-ul inainte de a semnaliza condiia, acest lucru garanteaza ca condiia nu poate fi semnalata (i, prin urmare, ignorata) intre momentul in care un fir blocheaza mutex-ul i momentul in care ateapta pe variabila de condiie. pthread_cond_timedwait deblocheaza atomic mutex i ateapta pe cond, la fel ca pthread_cond_wait, dar limiteaza i durata ateptarii. Daca cond nu a fost semnalata in intervalul de timp specificat de abstime, mutex-ul mutex este reacceptat din nou, iar pthread_cond_timedwait returneaza eroarea ETIMEDOUT. Parametrul abstime specifica un timp absolut, cu aceeai origine ca i time(2) i gettimeofday(2): un abstime de 0 corespunde la 00:00:00 GMT, 1 ianuarie 1970. pthread_cond_destroy distruge o variabila de condiie, eliberand resursele pe care le-ar putea conine. La intrarea in pthread_cond_destroy nu trebuie sa existe fire de execuie care sa atepte variabila de condiie. In implementarea ,,LinuxThreads", nu exista resurse asociate variabilelor de condiie, astfel incat pthread_cond_destroy nu face de fapt nimic, cu excepia verificarii faptului ca nu exista fire de execuie in ateptare. ANULARE pthread_cond_wait i pthread_cond_timedwait sunt puncte de anulare. Daca un fir este anulat in timp ce este suspendat intr-una din aceste funcii, firul ii reia imediat execuia, apoi blocheaza din nou argumentul mutex la pthread_cond_wait i pthread_cond_timedwait i, in final, executa anularea. In consecina, gestionarii de curaare sunt asigurai ca mutex este blocat atunci cand sunt apelai. SIGURANA SEMNALELOR ASINCRONE Funciile de condiie nu sunt sigure pentru semnale asincrone i nu ar trebui sa fie apelate de la un gestionar de semnal. In special, apelarea pthread_cond_signal sau pthread_cond_broadcast de la un gestionar de semnal poate bloca firul apelant. VALOAREA RETURNATA Toate funciile de variabila de condiie returneaza 0 in caz de succes i un cod de eroare diferit de zero in caz de eroare. ERORI-IEIRE pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast i pthread_cond_wait nu returneaza niciodata un cod de eroare. Funcia pthread_cond_timedwait returneaza urmatoarele coduri de eroare in caz de eroare: ETIMEDOUT Variabila de condiie nu a fost semnalata pana la expirarea timpului de ateptare specificat de abstime. EINTR pthread_cond_timedwait a fost intrerupt de un semnal. Funcia pthread_cond_destroy returneaza urmatorul cod de eroare in caz de eroare: EBUSY Unele fire sunt in prezent in ateptare pe cond. CONSULTAI I pthread_condattr_init(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), gettimeofday(2), nanosleep(2). EXEMPLU Se considera doua variabile partajate x i y, protejate de mutex-ul mut, i o variabila de condiie cond care trebuie semnalata ori de cate ori x devine mai mare decat y. int x,y; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; Ateptarea pana cand x este mai mare decat y se efectueaza dupa cum urmeaza: pthread_mutex_lock(&mut); while (x <= y) { pthread_cond_wait(&cond, &mut); } /* opereaza asupra lui x i y */ pthread_mutex_unlock(&mut); Modificarile lui x i y care pot face ca x sa devina mai mare decat y trebuie sa semnalizeze condiia, daca este necesar: pthread_mutex_lock(&mut); /* modificarea lui x i y */ if (x > y) pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mut); Daca se poate dovedi ca cel mult un singur fir in ateptare trebuie sa fie trezit (de exemplu, daca exista doar doua fire care comunica prin x i y), pthread_cond_signal poate fi utilizat ca o alternativa puin mai eficienta la pthread_cond_broadcast. In caz de indoiala, utilizai pthread_cond_broadcast. Pentru a atepta ca x sa devina mai mare decat y cu un timp de ateptare de 5 secunde, facei: struct timeval now; struct timespec timeout; int retcode; pthread_mutex_lock(&mut); gettimeofday(&now); timeout.tv_sec = now.tv_sec + 5; timeout.tv_nsec = now.tv_usec * 1000; retcode = 0; while (x <= y && retcode != ETIMEDOUT) { retcode = pthread_cond_timedwait(&cond, &mut, &timeout); } if (retcode == ETIMEDOUT) { /* a avut loc terminarea timpului de ateptare */ } else { /* opereaza asupra lui x i y */ } pthread_mutex_unlock(&mut); TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Pagini de manual de Linux 6.9.1 16 iunie 2024 pthread_cond_init(3)