太原网站优化工具方法合肥包河区最新消息
2026/6/28 15:04:01 网站建设 项目流程
太原网站优化工具方法,合肥包河区最新消息,阿里云域名,财务公司管理办法用最通俗的生活例子理解#xff1a;可重入函数#xff1a;像自动售货机 —— 你投币买水到一半#xff0c;有人打断你去买零食#xff0c;回来你继续投币#xff0c;售货机仍能正确给你水#xff08;逻辑独立、不依赖 “半完成” 的状态#xff09;#xff1b;不可重入…用最通俗的生活例子理解可重入函数像自动售货机 —— 你投币买水到一半有人打断你去买零食回来你继续投币售货机仍能正确给你水逻辑独立、不依赖 “半完成” 的状态不可重入函数像手工记账本 —— 你记到一半写了 “收入 100” 但没写 “元”有人打断你去记另一笔账回来你忘了之前写到哪账本就乱了依赖全局状态、操作不原子。核心定义函数类型核心定义通俗理解可重入函数函数执行过程中被异步打断如信号、中断、多线程调度再次调用重入后原流程和新流程都能正确执行结果不受影响多个人同时用、中途被打断再用都不会乱逻辑完全 “自给自足”不可重入函数函数执行过程中被异步打断后重入会导致数据错乱、逻辑异常、结果错误只能 “一次性干完”中途被打断就乱套依赖全局状态 / 共享资源关键前提“重入” 的核心是异步打断 再次调用—— 比如信号处理函数打断主程序的malloc又在信号处理函数里调用malloc就是典型的 “重入不可重入函数”必然出问题。本质区别为什么可重入函数 “不乱”可重入与不可重入的核心差异在于是否依赖 “非私有资源” 和 “非原子操作”用表格清晰对比对比维度可重入函数不可重入函数依赖全局 / 静态变量❌ 完全不用仅用参数 / 局部变量✅ 依赖比如strtok用静态变量存分割位置操作共享资源文件 / 内存❌ 仅操作函数内私有资源✅ 操作全局共享资源比如printf用全局输出缓冲区调用其他不可重入函数❌ 只调用可重入函数✅ 调用malloc/printf等不可重入函数非原子操作❌ 仅用原子操作一步完成✅ 有分步操作比如 “读全局变量→修改→写回”内存分配 / 释放❌ 不调用malloc/free改内存池✅ 调用malloc/free不可重入函数的 “坑”具体怎么乱的举个经典例子 ——strtok字符串分割函数不可重入// 不可重入的根源strtok用静态变量保存“上次分割的位置” char *strtok(char *str, const char *delim); // 主程序执行 char str[] a,b,c,d; strtok(str, ,); // 第一次调用静态变量存“b,c,d”的起始地址 // 此时信号触发信号处理函数里也调用strtok strtok(x,y,z, ,); // 静态变量被覆盖为“y,z”的起始地址 // 信号处理完主程序继续调用strtok strtok(NULL, ,); // 本应取“b”但静态变量被改实际取到“y”结果完全错了而可重入版本strtok_rrreentrant就解决了这个问题 —— 把 “分割位置” 从静态变量改成参数传入私有资源就算重入也不会乱// 可重入版本用saveptr局部变量保存分割位置不依赖全局 char *strtok_r(char *str, const char *delim, char **saveptr);常见的可重入 / 不可重入函数举例1. 可重入函数放心用尤其是信号处理 / 多线程这些函数仅依赖参数和局部变量无全局状态操作原子内存操作memcpy、memset、strcpy、strcmp仅操作传入的参数系统调用write、read、_exit、close内核级原子操作不依赖用户态全局资源基础运算abs、sqrt仅处理参数无副作用。2. 不可重入函数绝对不能在信号处理函数里用这些函数依赖全局 / 静态资源或有分步操作标准 IOprintf、fprintf、puts用全局输出缓冲区分步写入内存管理malloc、free、calloc操作全局内存池分步修改链表定时器sleep、alarm修改全局定时器状态字符串处理strtok静态变量、asctime静态缓冲区其他rand静态随机数种子、getenv全局环境变量表。关键应用场景为什么你必须关心这部分和“信号捕获” 强相关 ——信号处理函数必须用可重入函数否则必出问题场景 1信号处理打断不可重入函数主程序正在执行malloc修改全局内存池链表主程序malloc → 拆链表节点只拆了一半 ↓ 信号触发比如SIGINT 信号处理函数又调用malloc → 继续改同一个内存池链表 ↓ 信号处理完主程序继续 主程序malloc的链表已经乱了 → 内存泄漏/程序崩溃场景 2多线程调用不可重入函数多线程同时调用printf线程1printf(hello) → 写了“he”到全局缓冲区被调度走 线程2printf(world) → 覆盖缓冲区为“world”输出 线程1继续执行 → 缓冲区剩下的“llo”被输出 最终结果worldllo完全错乱核心原因信号处理是 “异步打断”多线程是 “并发执行”二者都会触发函数的 “重入”—— 不可重入函数扛不住这种场景可重入函数则完全没问题。如何编写可重入函数只要遵守以下规则就能写出安全的可重入函数绝不使用全局 / 静态变量所有数据都通过参数传入传值而非传指针共享或用函数内局部变量栈上分配每个调用独立绝不调用不可重入函数比如信号处理函数里不能用printf/malloc/sleep改用write可重入输出、_exit退出绝不操作共享资源不写全局文件、不修改全局配置仅操作函数内创建的私有资源只用原子操作避免 “读 - 改 - 写” 分步操作比如count是三步读 count→1→写回非原子改用原子指令如__sync_fetch_and_add不依赖函数执行顺序函数执行结果仅由输入参数决定不受 “是否被打断” 影响纯函数思想。正面例子可重入函数// 计算两数之和仅用参数和局部变量无全局依赖 int add(int a, int b) { int temp a b; // 局部变量栈上分配每个调用独立 return temp; } // 信号处理函数里的可重入输出用write替代printf void sig_handler(int sig) { char msg[] signal caught\n; write(1, msg, sizeof(msg)-1); // write是可重入的系统调用 _exit(0); // _exit是可重入的退出函数exit不可重入 }反面例子不可重入函数int count 0; // 全局变量 // 不可重入依赖全局变量count是非原子操作 int increment() { count; // 读count→1→写回中途被打断会乱 return count; }核心总结核心判断可重入函数 “自给自足”仅用参数 / 局部变量不可重入函数 “依赖外部状态”全局 / 静态 / 共享资源关键风险不可重入函数被异步打断信号/ 并发调用多线程会导致数据错乱可重入函数则安全实战要求信号处理函数、多线程核心逻辑必须用可重入函数禁用printf/malloc等不可重入函数编写规则不碰全局、不调不可重入函数、只用原子操作、结果仅由参数决定。简单说可重入函数是 “不怕打断的函数”不可重入函数是 “一打断就乱的函数”—— 在异步 / 并发场景下选可重入函数是唯一安全的选择。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询