news 2026/7/2 20:01:40

C 库的非线程安全函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C 库的非线程安全函数

我们先来看一段代码:

#include <time.h> int main() { time_t tNow = time(NULL); time_t tEnd = tNow + 1800; //注意下面两行的区别 struct tm* ptm = localtime(&tNow); struct tm* ptmEnd = localtime(&tEnd); char szTmp[50] = { 0 }; strftime(szTmp, 50, "%H:%M:%S", ptm); //struct tm* ptmEnd = localtime(&tEnd); char szEnd[50] = { 0 }; strftime(szEnd, 50, "%H:%M:%S", ptmEnd); printf("%s \n", szTmp); printf("%s \n", szEnd); return 0; }

程序执行结果如下所示:

20:53:48 20:53:48

很奇怪是不是?tNowtEnd明明相差 1800 秒。我们调整一下代码第9行的位置:

#include <time.h> int main() { time_t tNow = time(NULL); time_t tEnd = tNow + 1800; //注意下面两行的区别 struct tm* ptm = localtime(&tNow); char szTmp[50] = { 0 }; strftime(szTmp, 50, "%H:%M:%S", ptm); struct tm* ptmEnd = localtime(&tEnd); char szEnd[50] = { 0 }; strftime(szEnd, 50, "%H:%M:%S", ptmEnd); printf("%s \n", szTmp); printf("%s \n", szEnd); return 0; }

这次输出结果正确了:

20:25:44 20:55:44

为什么会出现这种情况呢?我们来看下localtime函数的签名:

struct tm* localtime(const time_t* timep);

这个函数返回值一个tm结构体指针类型,而我们外部并不需要释放这个指针指向的内存,因此我们断定这个函数内部一定使用了一个全局变量或函数内部的静态变量。这样的话,当再次调用这个函数时有可能前一次调用结果就被后一个结果覆盖了。我们简化一下这种模型:

int* func(int k) { static int result; result = k; return &result; }

当多个线程甚至单个线程调用这个函数时,如两个线程分别调用上述函数:

//线程1调用 int* p1 = func(1); //线程2调用 int* p2 = func(2);

那么 *p1和 *p2的结果会是什么呢?结论是可能是 1 也可能是 2,甚至既不是 1 也不是 2。原因我们在前面《为什么整形变量赋值操作不是原子》的小节已经介绍过了。

localtime这类 CRT 提供的具有上述行为的函数,我们称为非线程安全函数。因此我们在实际开发中应避免在多线程程序中使用这类函数,这类函数还有如strtok,甚至连操作系统提供的 socket 函数gethostbyname也不是线程安全的。

char* strtok(char* str, const char* delim); struct hostent* gethostbyname(const char* name);

为什么会出现这类函数呢?是因为最初编写很多 CRT 函数时,还没有多线程技术,所以很多函数内部实现都使用了函数内部的静态变量和全局变量。随着多线程技术的出现,很多函数出现了对应的多线程安全版本,如localtime_rstrtok_r。在这些函数内部很多改用了线程局部存储技术来替代原来使用静态变量或者全局变量的做法。

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

跟着导师选!2026年高校导师推荐的AI论文工具实用评测

AI写论文工具介绍 在2026年&#xff0c;随着学术写作的智能化趋势兴起&#xff0c;越来越多的人开始尝试利用AI写论文的工具。现有许多工具在撰写硕士、博士论文等较长的学术作品时&#xff0c;往往出现理论深度不足或逻辑结构欠缺的现象&#xff0c;根本无法满足专业论文写作…

作者头像 李华
网站建设 2026/7/2 19:59:22

通达信很牛的成交量找牛股副图

参数M1 2&#xff0c;100&#xff0c;5M2 2&#xff0c;100&#xff0c;35M3 2&#xff0c;100&#xff0c;135VOLUME:VOL,VOLSTICK; MAVOL1:MA(VOLUME,M1); MAVOL2:MA(VOLUME,M2); MAVOL3:MA(VOLUME,M3); VVOL:IF(CURRBARSCOUNT1 AND PERIOD5,VOL*240/FROMOPEN,DRAWNULL),NODR…

作者头像 李华
网站建设 2026/7/2 19:55:56

2026年AI论文软件深度剖析:哪几款能真正贴合学术规范和格式要求

你是否还在为撰写期刊论文而感到烦恼&#xff1f;面对浩繁的文献、繁琐的格式&#xff0c;以及接连不断的修改&#xff0c;很多科研工作者都感到写作效率低下的问题。别担心&#xff0c;接下来我将为你推荐四款实测的AI论文写作工具&#xff0c;这些工具涵盖了从文献检索到论文…

作者头像 李华
网站建设 2026/7/2 19:50:09

嵌入式设计模式:从状态机到观察者,代码结构怎么搭才清爽

写嵌入式程序的人&#xff0c;很少会一开始就考虑"设计模式"这回事。毕竟MCU上资源有限&#xff0c;RAM按KB算&#xff0c;Flash按MB算&#xff0c;哪有PC上那些花里胡哨的抽象继承多态。但干过三五个项目之后&#xff0c;你会发现一个规律——代码写到后面最难维护的…

作者头像 李华
网站建设 2026/7/2 19:49:14

EmbodiedClaw:对话式工作流如何革新具身AI开发范式

1. EmbodiedClaw&#xff1a;当具身AI学会“听”和“做”最近和几个做机器人和AI的朋友聊天&#xff0c;大家不约而同地提到了一个词&#xff1a;“具身智能”。这词儿听起来挺学术&#xff0c;但说白了&#xff0c;就是让AI不再只是屏幕里的代码&#xff0c;而是能通过物理身体…

作者头像 李华