You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SIGCHLD信号处理函数中调用write()是否会破坏程序?需保存恢复errno吗?

在SIGCHLD信号处理函数中调用write()是否会破坏errno?

答案是:确实会有破坏程序逻辑的风险,而你给出的先保存再恢复errno的写法,是完全正确且必要的操作。

为什么会有风险?

errno本质上是线程局部存储的全局变量(多线程场景)或全局变量(单线程场景)。当主程序执行过程中,某个系统调用失败后会设置errno,如果此时SIGCHLD信号触发,信号处理函数被调用,里面的write()如果执行失败(甚至部分实现中成功也可能修改errno),就会覆盖掉原来的errno值。等信号处理函数返回后,主程序继续执行时,会误以为之前的系统调用失败原因是write()设置的错误码,从而导致错误的逻辑分支。

举个具体场景:

  • 主程序调用open("/nonexist", O_RDONLY)失败,errno被设为ENOENT(文件不存在)。
  • 刚好此时子进程退出触发SIGCHLD信号,信号处理函数中的write()因输出缓冲区满失败,把errno改成了EAGAIN。
  • 如果没恢复errno,主程序后续检查errno时,会误以为open()返回了EAGAIN,而非实际的ENOENT,直接搞砸错误处理逻辑。

你的写法为什么合理?

  • 进入信号处理函数时立刻保存当前的old_errno,执行write()后再把errno恢复成原来的值,这样主程序完全感知不到信号处理函数对errno的修改,保证了错误状态的一致性。
  • 额外提一句:write()是POSIX标准规定的异步信号安全函数,所以在信号处理函数里调用它本身是合法的,不用担心其他线程安全或中断安全问题,唯一需要注意的就是errno的覆盖问题。

补充细节

哪怕write()调用成功,也建议保存恢复errno——因为POSIX标准并没有强制要求成功的系统调用必须保留errno原有值,有些实现可能会在成功时重置errno为0,这同样会破坏主程序的原有错误状态。

所以结论是:你的代码写法是正确的,一定要这样做来避免errno被意外修改导致的程序逻辑错误。

内容的提问来源于stack exchange,提问作者porton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:45:46