从不同线程调用相同函数时解决errno的机制是什么

What is the mechanism to address errno when calling same function from different threads

假设 main() 创建了两个线程。每个线程都得到它 errno(作为私有函数)。程序中有一个函数,可以被这两个线程调用。它是线程安全的。

编译器将如何安排此函数以确保其相同代码调用适当的 errno 函数?如何将“线程环境”传递给同一段代码?

编辑。问题不在于 errno 本身。问题是这个通用函数在执行时如何知道要调用哪个 errno同一段代码从哪里获得关于errno函数的不同线程特定信息?

编辑:它假设如果我将 3 个变量传递给函数,实际上还有几个变量在幕后传递,其中之一是这个 FS 处理器寄存器,它指向线程环境?如果我在这个常用函数中使用 say errno,这个函数如何知道它必须在其环境中搜索 errno - 这种机制是否嵌入在 errno 定义中?

结论: 由于将 errno 声明为 __thread 编译器知道此实体(变量或其他)是特定于线程的,并且可以访问该编译器使用函数的另一个“后台”输入 - 例如,处理器的 FS 寄存器始终包含指向线程环境的指针。

来自 C 标准(7.5 错误

errno

which expands to a modifiable lvalue201) that has type int and thread local storage duration,

所以每个线程都有自己的errno。

so-called公共函数在调用它的线程环境中被调用。

errno 是 thread-local,这意味着它以 implementation-dependent 的方式维护了一个单独的值 per-thread。

在我的环境中,它恰好被定义(宏)为 *__errno_location (),其中 __errno_location() “应 return 当前线程的 errno 变量的地址。” (ref).

在幕后,这使用 at least one case 中的 __thread 说明符,但它可以使用任何合适的 thread-local 存储机制,例如来自线程的特殊支持 library/operating 系统.

关于x86_64Linuxthread-local的信息可以reached through the fs register which points to thread-local data; on x86_64 Windows the gs register points to the Windows NT TIB which does the same. Here's a Linux example showing the generated code: https://godbolt.org/z/YeqEvdhnc