免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: aple_smx
打印 上一主题 下一主题

再谈localtime_r和mktime [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-07-30 11:30 |只看该作者
回复 1# aple_smx


陈年旧帖被我翻起来,诸位勿怪。

昨天我与同事分析一个多线程应用的core,由于代码里无意中使用了localtime,计划改为localtime_r,顺便上网查资料,发现网上好多地方都在转载一篇文章,大谈什么localtime_r其实也是不安全的,该文出世之后弄得好多人都不敢再用 _r 类的函数了,起码我同事坚决认为换用localtime_r肯定解决不了问题。本贴楼主估计也是看了那个文章(或者别的地方转载的),认为localtime_r不安全,所以上来发问。

其实,localtime_r到底安全不安全,不能一概而论,特别是不能因为原文作者提到的glibc库对tzset()的实现有bug就把localtime_r一棍子打死。要知道c库随同操作系统有很多版本,不同厂家提供有不同的实现,glibc当年的这个版本的BUG,不能代表所有厂家的所有版本。

我用的是solaris10,SUN对自己实现的time类函数是这样说的(当然,别家可能不是这样):
  The asctime(), ctime(), gmtime(), and localtime()  functions are  safe  to  use  in multithread applications because they employ  thread-specific  data.   However,   their   use   is discouraged  because  standards  do  not  require them to be  thread-safe. The asctime_r() and  gmtime_r()  functions  are MT-Safe. The ctime_r(), localtime_r(), and tzset() functions
are MT-Safe in  multithread  applications,  as  long  as  no  user-defined function directly modifies one of the following variables: timezone, altzone, daylight,  and  tzname.  These four  variables are not MT-Safe to access. They are modified by the tzset() function in an MT-Safe manner.  The mktime(), localtime_r(), and ctime_r() functions call tzset().

翻译过来就是说:
  asctime(), ctime(), gmtime(), 以及localtime()这几个函数(的solaris版本)在多线程程序中被调用是安全的,因为它们的内部实现使用了“线程特定数据”技术。但还是不鼓励大家(在多线程程序中)使用它们,因为C标准并未要求这几个函数是多线程安全的(换句话说使用它们会带来移植性问题)。asctime_r() 和gmtime_r() 是多线程安全的。ctime_r()和localtime_r()以及tzset()函数也是多线程安全的,只要你不在自己的代码中直接修改timezone/altzone/daylight/tzname这四个(全局)变量就行。这4个变量不是多线程安全的(其实对任何全局变量的直接访问都不是多线程安全的)。 这4个变量由tzset()函数以一种多线程安全的方式进行修改(其实就是加锁)。而mktime()、localtime_r()和ctime_r()函数是使用tzset()这个函数(来使用4个全局变量的,所以是线程安全的)。

所以,起码solaris版本的localtime_r()是线程安全的,甚至连localtime()也是线程安全的(基于tsd技术,大家可以去看看“线程特定数据”的资料)。

为了进一步确认这个结论,防止solaris版的libc库也“说了不做”,导致tzset()函数内部其实并没有对4个全局变量进行加锁保护,我们翻出solaris的源代码来看看(solaris源码以opensolaris项目名义开源,贡献了绝大部分的源码,包括libc库)。源码我作为附件,这里说明如下:

time_gdata.c :  定义了传说中的那几个全局变量,以及用于保护它们的一把互斥锁。
localtime.c     :  定义了所有那些time族函数,可以看到localtime_r()内确实使用了锁,而且localtime()函数内部用tsd申请空间后直接调用了localtime_r()函数。


time.zip (20.63 KB, 下载次数: 241)

论坛徽章:
0
12 [报告]
发表于 2010-07-30 12:26 |只看该作者
看有本书说,线程安全的函数可以调用非线程安全的函数,只要调用时加锁就好了.所以不能说调用了非线程安全的函数就不安全了

论坛徽章:
0
13 [报告]
发表于 2010-07-30 12:30 |只看该作者
_r 貌似是可重入的意思

论坛徽章:
0
14 [报告]
发表于 2010-07-30 13:32 |只看该作者
我相信它是安全的。。

论坛徽章:
0
15 [报告]
发表于 2010-07-30 22:15 |只看该作者
localtime_r()应该说是线程安全的,但可能不是可充入的,因为实现可能使用了锁,可能是非递归锁,由此会导致死锁

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
16 [报告]
发表于 2010-08-05 11:44 |只看该作者
localtime_r和mktime是用来在时间分量和时间秒数之间进行转换的标准c函数。但是线程不安全。

有位大侠提 ...
aple_smx 发表于 2007-09-21 15:04

自己写了全套日期时间函数,线程安全的。

论坛徽章:
0
17 [报告]
发表于 2010-08-05 22:47 |只看该作者
楼上的兄弟能否提供下源码,十分感谢!

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
18 [报告]
发表于 2010-08-07 09:06 |只看该作者
本帖最后由 yulihua49 于 2010-08-07 09:10 编辑
楼上的兄弟能否提供下源码,十分感谢!
lanying_wzw 发表于 2010-08-05 22:47



    参加QQ群 SDBC 100807652
在群空间->群共享,下载SDBC5.tar.rar和SDBC5说明书,有专门的章节说日期时间。

.tar下来后,先看sdbc.readme。你只需编译string目录,include <datejul.h>,连接libstr.a。

SDBC是个百宝箱,里边可能有许多你用得到的东西。

论坛徽章:
0
19 [报告]
发表于 2010-08-07 09:35 |只看该作者
想找localtime_r的代码上google codesearch就能找到了

论坛徽章:
0
20 [报告]
发表于 2010-08-07 09:36 |只看该作者
算了,顺便附上查找结果:
http://www.google.com/codesearch ... &cd=1&ct=rc
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP