10.11 Thread-safe (thread-sichere Funktionen)
Die Thread-Programmierung kann nur mit Bibliotheken realisiert werden, die als thread-sicher (thread-safe) gelten. Denn auch die Bibliotheken müssen die parallele Ausführung erlauben, um nicht ins Straucheln zu geraten. Mit der Einführung von Glibc 2.0 wurden die Linux-Threads in den Bibliotheken implementiert und müssen nicht extra besorgt werden. Somit ist strcmp() – auch wenn schon über 15 Jahre alt – thread-safe.
readdir() hingegen ist z. B. nicht thread-safe. Das Problem mit readdir() ist, wenn mehrere Threads denselben DIR-Zeiger verwenden, dass sie immer den aktuellen Rückgabewert vom zuvor erhaltenen Thread überschreiben. Als Alternative für Funktionen, die nicht als thread-safe gelten (auch wenn es nicht sehr viele sind), wurden thread-sichere Schnittstellen, die in der Regel mit der Endung _r (reentrante-Funktionen) gekennzeichnet wurden, eingeführt. Die thread-sichere Alternative zu readdir() lautet somit readdir_r().
Die Endung _r zeigt Ihnen außerdem nicht nur, dass die Funktion thread-sicher ist, sondern auch, dass diese Funktion keinen internen statischen Puffer verwendet (der beim Aufruf derselben Funktion in mehreren Threads jedes Mal überschrieben wird). Hierzu eine kurze Liste zu einigen gängigen Reentrante-Funktionen, deren genauere Syntax und Verwendung Sie bitte der entsprechenden Man-Page entnehmen.
Tabelle 10.1
Nicht thread-sichere Funktionen und die Alternativen
nicht thread-sicher
|
Thread-sicher
|
Bedeutung
|
getlogin
|
getlogin_r
|
Loginname ermitteln
|
ttyname
|
ttyname_r
|
Terminalpfadname ermitteln
|
readdir
|
readdir_r
|
Verzeichniseinträge lesen
|
strtok
|
strtok_r
|
String anhand Tokens zerlegen
|
asctime
|
asctime_r
|
Zeitfunktion
|
ctime
|
ctime_r
|
Zeitfunktion
|
gmtime
|
gmtime_r
|
Zeitfunktion
|
localtime
|
localtime_r
|
Zeitfunktion
|
rand
|
rand_r
|
(Pseudo-)Zufallszahlen generieren
|
getpwuid
|
getpwuid_r
|
Eintrag in /etc/passwd erfragen (via UID)
|
getpwnam
|
getpwnam_r
|
Eintrag in /etc/passwd erfragen (via Loginname)
|
getgrgid
|
getgrgid_r
|
Eintrag in /etc/group erfragen (via GID)
|
getgrnam
|
getgrnam_r
|
Eintrag in /etc/group erfragen (via Gruppenname)
|
|