首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Linux中是否有获得当前线程ID的异步安全方法?

问在Linux中是否有获得当前线程ID的异步安全方法?
EN

Stack Overflow用户
提问于 2014-02-13 02:14:49
回答 1查看 1.5K关注 0票数 5

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

还有这个答案声称所有直接(而不是多路)的系统都是异步安全的,但没有提供任何证据。

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

它不必是"Linux线程ID“--任何一致的线程ID都可以。例如,pthread_self将是很棒的,但是没有任何东西声称它是异步安全的。如果我们检查该方法在glibc中的实现,它将遵从THREAD_SELF宏,该宏如下所示:

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

看起来这应该是异步安全的,如果所讨论的线程是在填充gs重新注册程序的制度下创建的(我不确定Linux中的所有线程都是异步安全的)。看着标头让我很害怕..。

EN

回答 1

Stack Overflow用户

发布于 2014-06-24 16:04:24

正如在来自dlopen()ed库的线程变量?中提到的,您提供了(重点是我的):

当变量位于主可执行文件或直接链接的DSO中时,__thread变量通常符合要求(至少在Linux/x86上是如此)。 但是,当DSO是dlopen()ed (并且不使用初始-exec模型)时,从给定线程第一次访问TLS变量会触发对malloc的调用.

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

  1. 在创建子线程之前阻止对父线程感兴趣的信号。
  2. 在调用pthread_create之后,解除阻塞父线程中那些有趣的信号。
  3. 在子线程中,初始化__thread变量并解除阻塞这些有趣的信号。

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

代码语言:javascript
复制
__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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21743889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档