Vorhandene Bibliotheken arbeiten nicht immer korrekt, wenn sie von mehreren Threads gleichzeitig aufgerufen werden.
int rand(void)
Implementation (z.B.):
int _rand_seed = 0; int rand(void) { _rand_seed = (A * _rand_seed + B) % RAND_MAX; return(_rand_seed); }
Schreibzugriff auf _rand_seed erzeugt Race Condition
"Wrapper" um alte Funktion:
pthread_mutex_t _rand_lock = PTHREAD_MUTEX_INITIALIZER; int rand(void) { int rc; pthread_mutex_lock(&_rand_lock); rc = rand_old(); pthread_mutex_unlock(&_rand_lock); return(rc); }
Vorteil: Interface bleibt gleich
Nachteil: schlechte Performance (Serialisierung)
Problem bleibt bei Abhängigkeit mehrerer Bibliotheksroutinen untereinander (z.B. bei globaler Benutzung von errno)
ersetze globale Variable _rand_seed durch thread-eigene Variable:
int rand_r(int * seed_p) { *seed_p = (A * (*seed_p) + B) % RAND_MAX; return(*seed_p); }
Vorteil: bessere Performance (paralle Ausführung mehrerer Calls)
Nachteil: Änderungen beim aufrufenden Programm nötig
Für einige UNIX-Standard-Routinen wurden solche "thread-sicheren" Interfaces eingeführt (z.B. rand_r, getlogin_r)