Linux多线程编程问题

Linux多线程编程问题

ID:39465617

大小:79.00 KB

页数:7页

时间:2019-07-04

Linux多线程编程问题_第1页
Linux多线程编程问题_第2页
Linux多线程编程问题_第3页
Linux多线程编程问题_第4页
Linux多线程编程问题_第5页
资源描述:

《Linux多线程编程问题》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、Linux多线程编程问题1重入问题传统的UNIX没有太多考虑线程问题,库函数里过多使用了全局和静态数据,导致严重的线程重入问题。1.1–D_REENTRANT/-pthread和errno的重入问题。所先UNIX的系统调用被设计为出错返回-1,把错误码放在errno中(更简单而直接的方法应该是程序直接返回错误码,或者通过几个参数指针来返回)。由于线程共享所有的数据区,而errno是一个全局的变量,这里产生了最糟糕的线程重入问题。比如:do{bytes=recv(netfd,recvbuf,buflen,0);}while

2、(bytes!=-1&&errno!=EINTR);在上面的处理recv被信号打断的程序里。如果这时连接被关闭,此时errno应该不等于EINTR,如果别的线程正好设置errno为EINTR,这时程序就可能进入死循环。其它的错误码处理也可能进入不可预测的分支。在线程需求刚开始时,很多方面技术和标准(TLS)还不够成熟,所以在为了解决这个重入问题引入了一个解决方案,把errno定义为一个宏:externint*__errno_location(void);#defineerrno(*__errno_location())在

3、上面的方案里,访问errno之前先调用__errno_location()函数,线程库提供这个函数,不同线程返回各自errno的地址,从而解决这个重入问题。在编译时加-D_REENTRANT就是启用上面的宏,避免errno重入。另外-D_REENTRANT还影响一些stdio的函数。在较高版本的gcc里,有很多嵌入函数的优化,比如把printf(“Hello”);优化为puts(“hello”);之类的,有些优化在多线程下有问题。所以gcc引入了–pthread参数,这个参数出了-D_REENTRANT外,还校正

4、一些针对多线程的优化。因为宏是编译时确定的,所以没有加-D_REENTRANT编译的程序和库都有errno重入问题,原则上都不能在线程环境下使用。不过在一般实现上主线程是直接使用全局errno变量的,也就是__errno_location()返回值为全局&errno,所以那些没加-D_REENTRANT编译的库可以在主线程里使用。这里仅限于主线程,有其它且只有一个固定子线程使用也不行,因为子线程使用的errno地址不是全局errno变量地址。对于一个纯算法的库,不涉及到errno和stdio等等,有时不加_REENTRA

5、NT也是安全的,比如一个纯粹的加密/解谜函数库。比较简单的判断一个库是否有errno问题是看看这个库是使用了errno还是__errno_location():readelf-slibxxx.so

6、greperrno另外一个和errno类似的变量是DNS解析里用到的h_errno变量,这个变量的重入和处理与errno一样。这个h_errno用于gethostbyXX这个系列的函数。1.1库函数重入早期很多unix函数设计成返回静态buffer。这些函数都是不能重入的。识别这些函数有几个简单的规则:1.1.1stdio函数

7、是可以重入的。这是因为stdio函数入口都会调用flockfile()锁定FILE。另外stdio也提供不锁定(非重入)的函数,这些函数以_unlock结尾,具体参见manunlocked_stdio。利用这些特性可以做到多个stdio的互斥操作。如:flockfile(fp);fwrite_unlocked(rec1,reclen1,1,fp);fwrite_unlocked(rec2,reclen2,1,fp);funlockfile(fp);1.1.2返回动态分配数据的函数,这些一般是可以重入的。这些函数的特点是返

8、回的指针需要显式释放,用free或者配对的释放函数。如:getaddrinfo/freeaddrinfomalloc/strdup/calloc/freefopen/fdopen/popen/fcloseget_current_dir_name/freeasprintf/vasprintf/freegetline/getdelim/freeregcomp/regfree1.1.3函数返回一个和输入参数无关的数据,而且不需要free的大部分情况下是不可重入的。如gmtime,ntoa,gethostbyname…1.1.4

9、函数依赖一个全局数据,在多次或者多个函数间维护状态的函数是不可重入的。如getpwent,rand…1.1.5带有_r变体的函数都是不可重入的。这些函数大部分是上面两类的。这些变体函数是可重入的代替版本。可以用下面命令查看glibc有多少这种函数:readelf-s/lib/libc.so.6

10、grep_r@这些函数

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。