POSIX 线程安全 摘录
来源:互联网 发布:小米手机数据恢复软件 编辑:程序博客网 时间:2024/06/08 06:13
判断一个函数是否线程安全不是一件很容易的事情。但是读者可以通过下面这几条确定一个函数是线程不安全的。
a, 函数中访问全局变量和堆。
b, 函数中分配,重新分配释放全局资源。
c, 函数中通过句柄和指针的不直接访问。
d, 函数中使用了其他线程不安全的函数或者变量。
因此在编写线程安全函数时,要注意两点:
1, 减少对临界资源的依赖,尽量避免访问全局变量,静态变量或其它共享资源,如果必须要使用共享资源,所有使用到的地方必须要进行互斥锁 (Mutex) 保护;
2, 线程安全的函数所调用到的函数也应该是线程安全的,如果所调用的函数不是线程安全的,那么这些函数也必须被互斥锁 (Mutex) 保护
一个函数想要成为可重入的函数,必须满足下列要求:
a) 不能使用静态或者全局的非常量数据
b) 不能够返回地址给静态或者全局的非常量数据
c) 函数使用的数据由调用者提供
d) 不能够依赖于单一资源的锁
e) 不能够调用非可重入的函数
因为多线程技术和线程安全概念出现得相对较晚,所以 POSIX规范中收纳的一些函数并不符合线程安全要求。
下表是 UNIX环境高级编程列出 POSIX.1规范中的非线程安全的函数:
POSIX.1 规范中的非线程安全函数
asctimeecvtgethostentgetutxlineputc_unlocked
basenameencryptgetlogingmtimeputchar_unlocked
catgetsendgrentgetnetbyaddrhcreateputenv
cryptendpwentgetnetbynamehdestroypututxline
ctimeendutxentgetopthsearchrand
dbm_clearerrfcvtgetprotobynameinet_ntoareaddir
dbm_closeftwgetprotobynumberL64asetenv
dbm_deletegetcvtgetprotobynumberlgammasetgrent
dbm_errorgetc_unlockedgetprotoentlgammafsetkey
dbm_fetchgetchar_unlockedgetpwentlgammalsetpwent
dbm_firstkeygetdategetpwnamlocaleconvsetutxent
dbm_nextkeygetenvgetpwuidlrand48strerror
dbm_opengetgrentgetservbynamemrand48strtok
dbm_storegetgrgidgetservbyportnftwttyname
dirnamegetgrnamgetserventnl_langinfounsetenv
dlerrorgethostbyaddrgetutxentptsnamewcstombs
drand48gethostbynamegetutxidptsnameectomb
目前大部分上述函数目前已经有了对应的线程安全版本的实现,例如:针对 getpwnam的 getpwnam_r(),( 这里的 _r表示可重入 (reentrant),如前所述,可重入的函数都是线程安全的)。 在多线程软件开发中,如果需要使用到上所述函数,应优先使用它们对应的线程安全版本。而对于某些没有线程安全版本的函数,开发人员可按自己需要编写线程安全版本的实现。
在编写自己的线程安全版本函数之前,应首先仔细阅读 POSIX标准对函数的定义,以及通过充分的测试熟悉函数的输入和输出。理论上来说,所有的线程安全的版本函数应该与非线程安全版本函数在单线程环境下表现一致。
a, 函数中访问全局变量和堆。
b, 函数中分配,重新分配释放全局资源。
c, 函数中通过句柄和指针的不直接访问。
d, 函数中使用了其他线程不安全的函数或者变量。
因此在编写线程安全函数时,要注意两点:
1, 减少对临界资源的依赖,尽量避免访问全局变量,静态变量或其它共享资源,如果必须要使用共享资源,所有使用到的地方必须要进行互斥锁 (Mutex) 保护;
2, 线程安全的函数所调用到的函数也应该是线程安全的,如果所调用的函数不是线程安全的,那么这些函数也必须被互斥锁 (Mutex) 保护
一个函数想要成为可重入的函数,必须满足下列要求:
a) 不能使用静态或者全局的非常量数据
b) 不能够返回地址给静态或者全局的非常量数据
c) 函数使用的数据由调用者提供
d) 不能够依赖于单一资源的锁
e) 不能够调用非可重入的函数
因为多线程技术和线程安全概念出现得相对较晚,所以 POSIX规范中收纳的一些函数并不符合线程安全要求。
下表是 UNIX环境高级编程列出 POSIX.1规范中的非线程安全的函数:
POSIX.1 规范中的非线程安全函数
asctimeecvtgethostentgetutxlineputc_unlocked
basenameencryptgetlogingmtimeputchar_unlocked
catgetsendgrentgetnetbyaddrhcreateputenv
cryptendpwentgetnetbynamehdestroypututxline
ctimeendutxentgetopthsearchrand
dbm_clearerrfcvtgetprotobynameinet_ntoareaddir
dbm_closeftwgetprotobynumberL64asetenv
dbm_deletegetcvtgetprotobynumberlgammasetgrent
dbm_errorgetc_unlockedgetprotoentlgammafsetkey
dbm_fetchgetchar_unlockedgetpwentlgammalsetpwent
dbm_firstkeygetdategetpwnamlocaleconvsetutxent
dbm_nextkeygetenvgetpwuidlrand48strerror
dbm_opengetgrentgetservbynamemrand48strtok
dbm_storegetgrgidgetservbyportnftwttyname
dirnamegetgrnamgetserventnl_langinfounsetenv
dlerrorgethostbyaddrgetutxentptsnamewcstombs
drand48gethostbynamegetutxidptsnameectomb
目前大部分上述函数目前已经有了对应的线程安全版本的实现,例如:针对 getpwnam的 getpwnam_r(),( 这里的 _r表示可重入 (reentrant),如前所述,可重入的函数都是线程安全的)。 在多线程软件开发中,如果需要使用到上所述函数,应优先使用它们对应的线程安全版本。而对于某些没有线程安全版本的函数,开发人员可按自己需要编写线程安全版本的实现。
在编写自己的线程安全版本函数之前,应首先仔细阅读 POSIX标准对函数的定义,以及通过充分的测试熟悉函数的输入和输出。理论上来说,所有的线程安全的版本函数应该与非线程安全版本函数在单线程环境下表现一致。
- POSIX 线程安全 摘录
- 摘录 线程安全总结
- POSIX多线程 - 线程安全和可重入
- Posix 线程
- Posix线程
- POSIX线程
- POSIX 线程
- POSIX线程
- POSIX线程
- POSIX线程
- posix线程
- POSIX线程
- POSIX线程
- POSIX线程
- POSIX线程-什么是线程
- POSIX 线程详解
- POSIX 线程 – pthread_sigmask
- Posix线程编程指南
- 迭代循环文件夹的处理方法
- zoj 2747 Paint the Wall
- JUnit4单元测试
- Android OpenGL学习笔记(二)之----三角形的绘制.
- struts spring 整合详解
- POSIX 线程安全 摘录
- iptables二层过滤机制详解
- eval 妙用
- 谷歌研发人脸识别手机应用 拍照可获个人信息
- android线程 message和runnable
- poj1159
- 出现“将截断字符串或二进制数据。语句已终止。 ”错误
- java FTP传文件 .
- 02-05 控制AutoCAD环境(五) 设置AutoCAD选项