====== Praca s vlaknami ====== Vlakna v pthreade maju niekolko zakuti: ===== pthread_cond_wait ===== pthread_cond_wait v kombinacii so pthread_cond_signal moze skoncit v neprijemnom death-locku: 1. vlakno sa snazi nieco poslat 2. vlakno pocuva a v pripade zaujimavej udalosti zavola funkciu DataReceive 1. vlakno vola: lock Application lock Library pthread_cond_wait unlock Library unlock Application 2. vlakno vola dokolecka: lock Library kontrola_spojenia ak send presiel: pthread_cond_signal unlock Library (*) ... ... lock Library (*) ak zaujimava udalost zavola DataReceive unlock Library Problem nastane vtedy ak DataReceive bude v sebe obsahovat Lock Application (napr. na aplikacne data - co moze byt korektna poziadavka). Ak sa stane, ze sa system nepresheduluje medzi unlock a lock Library (oznacene *) tak sa ani nikdy z cond_waitu nedostane thread, lebo ostane v mutexe ktory drzi aj DataReceive. TODO: obrazok, lebo je to neprehladne :-) ===== zistenie vlakna drizaceho lock ===== Majme situaciu, ze niektore vlakno co by nemalo stoji na locku. Zsitit ktoremu vlaknu patri lock sa da cez gdb v premennej pthreadu __data.__owner: (gdb) thread 2 - prepneme do vlakna 2 [Switching to thread 2 (Thread 0xb6d94b90 (LWP 22026))]#0 0xb771f424 in __kernel_vsyscall () (gdb) bt #0 0xb771f424 in __kernel_vsyscall () #1 0xb76fec99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0 #2 0xb76fa0c4 in _L_lock_89 () from /lib/i686/cmov/libpthread.so.0 #3 0xb76f99f2 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0 #4 0x080484a6 in thread (x=0x0) at mutex_owner.c:8 #5 0xb76f84c0 in start_thread () from /lib/i686/cmov/libpthread.so.0 #6 0xb767784e in clone () from /lib/i686/cmov/libc.so.6 (gdb) up 4 - vo framestacku sa dostaneme na uroven 4 (v QtCreatore staci klik :-) ) #4 0x080484a6 in thread (x=0x0) at mutex_owner.c:8 8 pthread_mutex_lock(&mutex); (gdb) print mutex.__data.__owner - vypiseme ttid $1 = 22025 (gdb) Ktore vlakno to je sa da cez: ps -eLf pripade vypis debug infa to zobrazuje ako LWP. ===== zoznam funkcii ktore nie su thread-safe a teda sa nesmu pouzivat v inom ako hlavnom vlakne ===== Hrubym su relativne caso pouzivane funkcie. **asctime()** **basename()** catgets() crypt() **ctime()** dbm_clearerr() dbm_close() dbm_delete() dbm_error() dbm_fetch() dbm_firstkey() dbm_nextkey() dbm_open() dbm_store() **dirname()** dlerror() drand48() ecvt() encrypt() endgrent() endpwent() endutxent() fcvt() ftw() gcvt() getc_unlocked() getchar_unlocked() **getdate()** **getenv()** getgrent() getgrgid() getgrnam() gethostbyaddr() gethostbyname() gethostent() getlogin() getnetbyaddr() getnetbyname() getnetent() getopt() getprotobyname() getprotobynumber() getprotoent() getpwent() getpwnam() getpwuid() getservbyname() getservbyport() getservent() getutxent() getutxid() getutxline() **gmtime()** hcreate() hdestroy() hsearch() inet_ntoa() l64a() lgamma() lgammaf() lgammal() localeconv() **localtime()** lrand48() mrand48() nftw() nl_langinfo() ptsname() putc_unlocked() putchar_unlocked() **putenv()** pututxline() **rand()** **readdir()** **setenv()** setgrent() setkey() setpwent() setutxent() **strerror()** **strtok()** ttyname() **unsetenv()** wcstombs() wctomb()