
第一类:不保护共享变量的函数,
a, 函数中访问全局变量和堆。共享变量在多线程中是共享数据比如全局变量和堆,如果不保护共享变量,多线程时会出bug。
可以通过同步机制来保护共享数据,比如加锁。
第二类:函数中分配,重新分配释放全局资源。
与上面第一点基本相同,通过加锁可解决
第三类:返回指向静态变量的指针的函数,函数中通过句柄和指针的不直接访问。
比如,我们要计算a,b两个变量的和,于是将a,b的指针传入某一个函数,然而此时可能有另一个线程改变了a,b的值,此时在函数中我们通过地址取到的两个数的值已经改变了,所以计算出的结果也就是错的了。
又比如某些函数(如gethostbyname)将计算结果放在静态结构中,并返回一个指向这个结构的指针。在多线程中一个线程调用的结构可能被另一个线程覆盖。可以通过重写函数和加锁拷贝技术来消除。加锁拷贝技术指在每个位置对互斥锁加锁,调用线程不安全函数,动态的为结果分配存储器,拷贝函数返回的结构,然后解锁。
第四类:调用线程不安全函数
常见的系统线程不安全函数:
线程不安全函数 | 线程不安全 类 | unix线程安全版本 |
rand | 2 | rand_r |
strtok | 2 | strtok_r |
asctime | 3 | asctime_r |
ctime | 3 | ctime_r |
gethostbyaddr | 3 | gethostbyaddr_r |
geyhostbyname | 3 | gethostbyname_r |
inet_ntoa | 3 |
|
localtime | 3 | localtime_r |
UNIX环境高级编程列出 POSIX.1规范中的非线程安全的函数:
asctime | ecvt | gethostent | getutxline | putc_unlocked |
---|---|---|---|---|
basename | encrypt | getlogin | gmtime | putchar_unlocked |
catgets | endgrent | getnetbyaddr | hcreate | putenv |
crypt | endpwent | getnetbyname | hdestroy | pututxline |
ctime | endutxent | getopt | hsearch | rand |
dbm_clearerr | fcvt | getprotobyname | inet_ntoa | readdir |
dbm_close | ftw | getprotobynumber | L64a | setenv |
dbm_delete | getcvt | getprotobynumber | lgamma | setgrent |
dbm_error | getc_unlocked | getprotoent | lgammaf | setkey |
dbm_fetch | getchar_unlocked | getpwent | lgammal | setpwent |
dbm_firstkey | getdate | getpwnam | localeconv | setutxent |
dbm_nextkey | getenv | getpwuid | lrand48 | strerror |
dbm_open | getgrent | getservbyname | mrand48 | strtok |
dbm_store | getgrgid | getservbyport | nftw | ttyname |
dirname | getgrnam | getservent | nl_langinfo | unsetenv |
dlerror | gethostbyaddr | getutxent | ptsname | wcstombs |
drand48 | gethostbyname | getutxid | ptsname | ectomb |
目前大部分上述函数目前已经有了对应的线程安全版本的实现,例如:针对 getpwnam的 getpwnam_r(),( 这里的 _r表示可重入 (reentrant),如前所述,可重入的函数都是线程安全的)。在多线程软件开发中,如果需要使用到上所述函数,应优先使用它们对应的线程安全版本。
因此在编写线程安全函数时,要注意两点:
- 1, 减少对临界资源的依赖,尽量避免访问全局变量,静态变量或其它共享资源,如果必须要使用共享资源,所有使用到的地方必须要进行互斥锁 (Mutex) 保护;
- 2, 线程安全的函数所调用到的函数也应该是线程安全的,如果所调用的函数不是线程安全的,那么这些函数也必须被互斥锁 (Mutex) 保护;