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)