====== 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()