根据传统的 POSIX,errno
它只是一个整数左值,它可以很好地与. 一起fork
工作,但显然不能与线程一起工作。根据 pthreads,errno
是一个线程局部整数左值。在 Linux/NTPL 下,作为实现细节,errno 是一些“扩展为返回整数左值的函数的宏”。
在我的 Debian 系统上,这似乎是*__errno_location ()
,在我见过的其他一些系统上,例如&(gettib()->errnum
.
TL;DR
假设我曾经clone
创建过一个线程,我可以直接调用errno
并期望它会起作用,还是我必须做一些特殊的雨舞?例如,我是否需要读取线程信息块中的一些特殊字段,或者一些特殊的 TLS 值,或者,我是否需要设置 glibc 以某种方式存储错误值的线程局部变量的地址?可能是什么__set_errno_location()
?
或者,它会“正常工作”吗?
不可避免地,有人会试图回答“只使用 phtreads”——请不要。我不想使用 pthreads。我想要clone
。我不想要 pthread 的任何不明智的功能,我不想处理它的任何怪癖,也不想要实现这些怪癖的开销。我认识到 pthreads 中的大部分问题来自于它必须工作(而且,令人惊讶的是,它成功地工作)在一些已经有近 30 年历史的完全损坏的系统中,但这并不意味着它是对每个人和每种情况都必然是一件好事。在这种情况下,可移植性无关紧要。
在这种特殊情况下,我想要的只是启动另一个与父进程在同一地址空间中运行的进程,通过一个简单的锁(比如 futex)进行同步,并write
正常工作(这意味着我还必须能够errno
正确读取) . 尽可能少的开销,不需要甚至不需要其他功能或特殊行为。