errno 的实现
内容提要
在 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,以确保在线程库初始化之前可用。
延伸解读
POSIX 线程安全的演变
POSIX 标准的演变反映了对多线程编程的重视。早期的 errno 作为外部变量,导致线程不安全的问题。随着 POSIX Issue 6 的发布,errno 的定义被修改为可修改的左值宏,这为实现线程安全提供了可能性。理解这一变化有助于开发者在多线程环境中更好地处理错误码。
FreeBSD 的 errno 实现机制
FreeBSD 通过函数指针实现 errno 的线程安全,使用 __error() 函数来返回线程独立的错误存储。这种设计不仅提高了线程安全性,还避免了不必要的开销。开发者在使用 FreeBSD 时,应关注如何正确地链接和使用 libthr,以确保在多线程应用中正确处理 errno。
线程安全的实现细节
在 FreeBSD 中,libthr 通过构造函数和弱符号引用机制实现 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 的线程安全实现确保每个线程可以独立存储和访问错误码,避免了线程间的干扰。