Linux设置时区不影响已创建的进程解决办法

当你使用time()localtime_r()函数时,它们返回的是根据系统环境设置的本地时间。即使你在之前修改了时区,这些函数仍然会根据系统的时区设置来解析时间。

在Unix-like系统中,时区设置通常会影响到整个系统的各个进程。当你修改了时区设置后,它并不会影响已经创建的进程,因为它们在创建时已经确定了其所在的时区。

已经创建的进程的时区不会自动改变,因为它们在创建时已经确定了时区。但是,你可以通过以下方法让已经创建的进程切换到新修改的时区:

  1. 使用setenv()函数设置TZ环境变量,将其设置为新的时区。这将影响使用localtime()localtime_r()等函数获取时间信息的进程。示例代码如下:
 
csetenv("TZ", "Asia/Shanghai", 1);
tzset();
  1. 可以通过修改进程的TZ环境变量来切换时区。你可以使用putenv()函数将TZ环境变量设置为新的时区。示例代码如下:
 
cputenv("TZ=Asia/Shanghai");
tzset();

请注意,这种方法只影响当前进程及其子进程。其他已经创建的进程的时区不会受到影响。

总之,要使已经创建的进程切换到新修改的时区,你需要显式地设置或修改其TZ环境变量,并调用tzset()函数来重新初始化时间转换函数。

经测试,tzset函数可以将已创建的进程同步时区问题

我们可以使用time调用获取当前的时间,注意,这是以UTC表示的机器时间——自1970年1月1日0点以来的秒数

接着我们用localtime调用可以将time获取的时间转换为本地时间,从UTC 转换到本地时间会依靠时区信息进行调整。

对于一个daemon进程而言,如果每隔一段时间用time和localtime调用就可以定期获取当前时间的数值,但是如果在这个期间发生了时区设置转换会怎样呢?

或许你会觉得,那一定会出大问题——时区变了,localtime也会出现很大的调整。

嗯,接下来的结论就是后续的程序需要小心处理这种变化...... 很不幸,我们的感觉是错的!!!

如果时区的设置变化了,localtime转换的时间依然与之前没有什么不同,除非程序再次启动!!!

Linux的时区设置通过几个不同的途径完成。

一方面可以通过设置环境变量TZ来指定时区,例如TZ=Asia/Shanghai,可以将时区指定为上海所在的时区,时区的配置出现在/usr/share/zoneinfo/Asia/Shanghai文件当中(Redhat环境);

如果没有指定TZ环境变量,那么缺省的时区配置文件可以用/etc/localtime来获得,这个文件可能是一个符号链接指向真实的文件,也有可能就是将/usr/share/zoneinfo下的文件复制过来达到所要的结果。

由于环境变量由各个进程组单独继承,那么在设置时区之后很难改变其他进程组的环境变量,

所以一般的系统很少直接设置TZ环境变量,而是由/etc/localtime文件来指示时区位置。

既然如此,为什么设置了时区以后,已经运行的daemon程序在使用localtime函数调用时没有使用新时区呢?

这个可以通过glibc的源码来回答。

localtime等涉及到本地所在时区的函数在调用的时候会先调用tzset这个函数,这一点可以通过tzset函数的manpage看出来。

tzset完成的工作是把当前时区信息(通过TZ环境变量或者/etc/localtime)读入并缓冲。

事实上tzset在实现的时候是通过内部的 tzset_internal函数来完成的,显式的调用tzset会以显式的方式告知tzset_internal,而单独调用localtime的时候是以隐式的方式告知tzset_internal,前者将强制tzset不管何种情况一律重新加载TZ信息或者/etc/localtime,而后者则是只有在TZ发生变化,或者加载文件名发生变化的时候才会再次加载时区信息。

因此,如果只是/etc/localtime的内容发生了变化,而文件名" /etc/localtime"没有变化,则不会再次加载时区信息,导致localtime函数调用仍然以老时区转换UTC时间到本地时间。

结论:对localtime的反复调用,如果要考虑时区变化的因素,最好显式的调用一次tzset。或许今后的glibc库会修正这个bug?至少我在glibc-2.3.5和2.4的版本上还看到这个问题。

进程除了修改环境变量和直接调用命令行,很难通过代码直接修改系统时间(date)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值