news 2026/5/10 1:40:11

localtime和gmtime获取的时间不可靠

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
localtime和gmtime获取的时间不可靠

多线程中使用localtimegmtime的风险

引言

在嵌入式设备管理中,我们经常会遇到设备需要在特定时间自动开关机的场景。然而,一个设备在预定关机后,意外地提前开机然后再次关机,这引起了我们的注意。本文将探讨这一现象背后的原因,并提供解决方案。

核心发现

我们发现,在多线程环境中,使用localtimegmtime函数 可能会导致不可预测的结果。具体来说,localtime的返回值可能会被gmtime的结果篡改,这是一个严重的线程安全问题。

问题分析与解决
1. 代码审查与日志分析

通过代码审查和日志分析,我们发现设备在定时检测到当前时间符合条件后,会执行关机操作。然而,日志显示云服务返回的时间与预期存在8小时的差异。

2. 增加日志与挂测

为了进一步诊断问题,我们在代码中增加了打印时间戳的日志,并进行了长时间的挂测。结果发现,时间戳偶尔会出现异常跳动,与实际时间相差8小时。

3. 函数替换与挂测

考虑到localtime是非线程安全的,我们将其替换为线程安全的localtime_r,并继续进行挂测。这次,时间戳显示正常,没有出现之前的异常。

根因探究

尽管localtime是非线程安全的,但时间相差8小时的现象仍然令人费解。我们考虑了以下可能的原因:

  1. 时区变更:我们首先怀疑时区被意外改变,但日志中没有发现任何修改痕迹。
  2. 返回值被修改:我们检查了业务,没有发现有地方使用了localtime的返回值并进行了修改。
  3. uClibc库问题:我们分析了uClibc库中localtime的实现,并发现localtimelocaltime_r在时区处理上是一致的。但官网下载的uClibc版本与AX平台的不一致,我们怀疑是实现上的差异。
深入分析

进一步分析发现,localtime不仅使用全局指针(这是非线程安全的表现),而且与gmtime共享同一个指针。这与glibc的行为不同,可能是问题的关键所在。

struct tm __time_tm; /* Global shared by gmtime() and localtime(). */
实验 验证

为了验证我们的结论,我们设计了一个多线程实验:

  1. 创建多个线程,其中一部分线程使用localtime获取时间,并打印小时数。
  2. 另一部分线程使用gmtime获取时间。
  3. 观察localtime获取的小时数是否为本地时间,结果显示localtime获取的小时数出现了UTC时间。

以下是实验的 代码示例 :

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <time.h> void* thread_localtime(void* arg) { while(1) { time_t rawtime; struct tm* timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); printf("Local tm_hour:%d\n", timeinfo->tm_hour); usleep(200*1000); } return NULL; } void* thread_gmtime(void* arg) { while(1) { time_t rawtime; struct tm* utc_info; time(&rawtime); utc_info = gmtime(&rawtime); printf("UTC tm_hour:%d\n", utc_info->tm_hour); usleep(200*1000); } return NULL; } int main() { pthread_t threads[10]; for (int i = 0; i < 10; i++) { if (i < 5) { pthread_create(&threads[i], NULL, thread_localtime, NULL); } else { pthread_create(&threads[i], NULL, thread_gmtime, NULL); } } // 等待所有线程完成 for (int i = 0; i < 10; i++) { pthread_join(threads[i], NULL); } return 0; }
结论

在多线程环境中,为了避免全局指针被篡改的风险,建议使用线程安全的函数,如localtime_r。这不仅可以避免潜在的线程安全问题,还可以确保程序的健壮性和可靠性。

localtime和gmtime获取的时间不可靠_localtime多线程-CSDN博客

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 1:35:44

颠覆性游戏串流革命:Sunshine自托管服务器一站式解决方案

颠覆性游戏串流革命&#xff1a;Sunshine自托管服务器一站式解决方案 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款革命性的自托管游戏串流服务器&#xff0c;专为…

作者头像 李华
网站建设 2026/5/10 1:34:31

助睿ETL入门实验指导

一、准备工作登录到助睿平台&#xff0c;点击数据集成点击新建项目输入项目名称&#xff0c;点击确定点击你创建的项目右上角的&#xff0c;点击打开项目点击元数据右键关系数据库&#xff0c;点击同步数据源点击文件库&#xff0c;再点击元数据&#xff0c;就会出现数据源&…

作者头像 李华
网站建设 2026/5/10 1:25:03

CANN/asc-devkit算子属性设置API

AddAttr 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitcode.com/ca…

作者头像 李华
网站建设 2026/5/10 1:25:02

CANN运行时错误上报接口

&#xfeff;# 22. 错误上报接口 【免费下载链接】runtime 本项目提供CANN运行时组件和维测功能组件。 项目地址: https://gitcode.com/cann/runtime 本章节描述错误上报接口&#xff0c;用于注册和上报各类预定义与自定义的错误信息。 使用须知int32_t ReportInnerErr…

作者头像 李华
网站建设 2026/5/10 1:21:31

基于Cursor-Agents-Kit构建AI编程智能体:从原理到团队实战指南

1. 项目概述&#xff1a;一个为开发者赋能的智能编码工具箱最近在GitHub上看到一个挺有意思的项目&#xff0c;叫sakshampandey1901/cursor-agents-kit。光看这个名字&#xff0c;很多开发者朋友可能就会心一笑——cursor这个词在编程圈里现在几乎成了AI辅助编码的代名词&#…

作者头像 李华