errno 的实现

💡 原文中文,约3000字,阅读约需8分钟。
📝

内容提要

在 POSIX 中,errno 被定义为可修改的左值宏,以支持线程安全。FreeBSD 通过函数指针实现 errno,单线程时使用全局变量,线程安全时则返回各线程独立的存储。

🎯

关键要点

  • POSIX 中 errno 被定义为可修改的左值宏,以支持线程安全。

  • 早期 POSIX 规定 errno 为外部变量,导致线程不安全。

  • POSIX Issue 6 删除了外部变量要求,允许实现者支持线程安全的 errno。

  • ISO C 标准在 C90/C89 时期不再要求 errno 为外部变量。

  • FreeBSD 中 errno 的实现通过函数指针实现,支持线程独立存储。

  • errno 宏调用 __error() 函数获取 int * 指针,确保每个线程有独立的 errno 存储。

  • libthr 通过构造函数和弱符号引用机制实现线程安全的 errno。

  • 线程安全版本的 errno 访问函数 __error_threaded 根据当前线程返回独立的错误存储。

  • 初始线程使用全局 __libsys_errno,以确保在线程库初始化之前可用。

延伸问答

errno 在 POSIX 中是如何定义的?

在 POSIX 中,errno 被定义为可修改的左值宏,以支持线程安全。

为什么早期的 POSIX 版本中 errno 不支持线程安全?

早期的 POSIX 规定 errno 为外部变量,导致所有线程共享同一个全局变量,从而无法实现线程安全。

FreeBSD 中 errno 是如何实现线程安全的?

FreeBSD 通过函数指针实现 errno,使用 __error() 函数返回每个线程独立的 errno 存储。

libthr 是如何确保 errno 线程安全的?

libthr 通过构造函数和弱符号引用机制替换 errno 的实现为线程安全版本。

在 FreeBSD 中,如何访问线程安全的 errno?

通过调用 __error_threaded 函数,当前线程可以访问其独立的 errno 存储。

errno 的实现对多线程程序有什么影响?

errno 的线程安全实现确保每个线程可以独立存储和访问错误码,避免了线程间的干扰。

➡️

继续阅读