gpt4 book ai didi

linux - 在 Linux 中是否有一种异步安全的方法来获取当前线程 ID?

转载 作者:IT王子 更新时间:2023-10-29 00:41:49 26 4
gpt4 key购买 nike

有什么方法可以从 Linux 中的信号处理程序获取当前线程 ID? getpid() 方法做我想做的,但不清楚它是否是异步安全的。 man 7 signal 提供了一个异步安全的 POSIX 方法列表,但这并没有告诉我们任何关于非 POSIX 方法的信息,例如 getpid()。据推测,Linux 添加的许多非 POSIX 方法中的一些是异步安全的,但我找不到列表。

还有this answer它声称所有直接(非多路复用)系统调用都是异步安全的,但没有提供任何证据。

目标是构建某种异步安全的线程本地存储,因为 __thread is not safe在一般情况下。

不必是“Linux 线程 ID”——任何一致的线程 ID 都可以。例如 pthread_self 会很棒,但没有人声称它是异步安全的。如果我们在 glibc Linux 中检查该方法的实现,它遵循 THREAD_SELF 宏,它看起来像:

# define THREAD_SELF \
({ struct pthread *__self; \
asm ("movl %%gs:%c1,%0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.self))); \
__self;})

似乎这应该是异步安全的,如果有问题的线程是在填充 gs 寄存器的机制下创建的(可能是 Linux 中的所有线程是,我不确定)。还在看that header让我很害怕......

最佳答案

Async-signal-safe access to __thread variables from dlopen()ed libraries? 中所述你提供的(重点是我的):

The __thread variables generally fit the bill (at least on Linux/x86), when the variable is in the main executable, or in a directly-linked DSO.

But when the DSO is dlopen()ed (and does not use initial-exec TLS model), the first access to TLS variable from a given thread triggers a call to malloc...

换句话说,它只需要一次访问该线程特定的变量就可以使它生效并使其在信号处理程序中可用。例如:

  1. 在创建子线程之前,在父线程中屏蔽您感兴趣的信号。
  2. 在调用 pthread_create 后取消阻塞父线程中那些有趣的信号。
  3. 在子线程中初始化您的 __thread 变量并解锁那些有趣的信号。

我通常将 unix 管道的写入端存储在特定于胎面的变量中,信号处理程序将信号编号写入该管道。管道的读取端在同一个线程中使用 select/epoll 注册,这样我就可以在信号上下文之外处理信号。例如:

__thread int signal_pipe; // initialized at thread start

extern "C" void signal_handler(int signo, siginfo_t*, void*)
{
unsigned char signo_byte = static_cast<unsigned>(signo); // truncate
::write(signal_pipe, &signo_byte, 1); // standard unix self pipe trick
}

关于linux - 在 Linux 中是否有一种异步安全的方法来获取当前线程 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21743889/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com