即使从 C++ 线程中使用 pthread_self() 获取线程 ID 是否可靠?

问题描述 投票:0回答:1

在Linux上,libstdc++不使用

pthread_create()
来创建线程,从这个bug可以看出:https://bugzilla.kernel.org/show_bug.cgi?id=218607(libpsx包装
pthread_create()
)拦截线程创建,但这在 C++ 线程上不起作用,这只能意味着 libstdc++ 不使用
pthread_create()
)。

我不是来报告错误或类似的事情的,所以现在介绍了这一点背景知识,让我们来讨论我的实际问题。

对于我的软件架构,我需要一个线程 ID。该线程可能是从 C 库或 C++ 库创建的。我无法控制这一点。我编写的函数(回调)(因此我控制的一些代码)是从这样的线程调用的。我需要从这个回调中获取线程 ID。

我的线程ID的要求:

  • ID 必须是唯一的(两个活动线程不能共享相同的 ID)。
  • 如果线程死亡后发生 ID 回收也没关系。
  • 我需要能够在 C 结构中“序列化”这个 ID。就像...只要底层线程保持活动状态,ID 中的
    memcpy()
    就会产生相同 ID 的另一个有意义的副本(ID 比较相等)(正如我之前所说,一旦线程死亡,回收线程 ID 就不是一个我的架构有问题)。

所以我的问题是:从 C++/libstdc++ 线程使用

pthread_self()
可靠吗?如果从 C++ 线程调用
pthread_self()
不可靠,您是否建议使用替代方法来生成线程 ID?

更多一点背景信息:我正在 FreeBSD 上创建一个辣椒沙箱(我正在 Linux 上使用 Landlock+seccomp 做一些非常相似的事情,所以 glibc/libstdc++ 问题对我来说也很重要......因此这个问题),但是我希望重用现有的 C/C++ 库。辣椒完全禁用环境权威。我正在包装从环境权限获取资源的 libc 函数。我的 libc 函数重写器通过 UNIX 未命名套接字将消息发送到位于沙箱外部的主管。考虑到任何线程都可能使用这些函数,请求包含线程 ID(因此需要能够在 C 结构中序列化线程 ID)并阻塞线程,直到收到匹配的回复。

c++ c pthreads glibc libstdc++
1个回答
0
投票

即使从 C++ 线程中使用 pthread_self() 获取线程 ID 是否可靠?

这取决于您想要依赖什么特征。 如果您使用的是 POSIX 系统,那么调用

pthread_self()
是安全的,并且总是会成功。 但是,当此类调用发生在 C++ 程序中时,POSIX 和 C++ 都不会定义结果
pthread_t
与发生调用的上下文中的
std::thread
的属性之间的任何关系。 即使您在不同的
std::thread
中调用也会得到不同的结果。

您可能会凭经验发现这样的关系,但这并不安全。 您可能会发现您的 C++ 实现记录了一种关系,并且在该实现的上下文中可以安全地依赖它,但这种依赖将构成可移植性问题。

你写:

对于我的软件架构,我需要一个线程 ID。该线程可能是从 C 库或 C++ 库创建的。我无法控制这一点。我编写的函数(回调)(因此我控制的一些代码)是从这样的线程调用的。我需要从这个回调中获取线程 ID。

问题在于这些规范中对“线程”的定义不够明确。 您需要知道或被告知您需要哪种线程的 ID,以便您可以使用适当的机制来获取 ID。如果您需要在同一个程序中容纳不同类型的线程,那么您需要做额外的工作。

前进的一种方法是要求使用pthreads,包括在C++程序中。 对于使用 pthread 并在

std::thread
和 pthread 之间保持稳定的 1:1 关系的 C++ 实现来说,这没什么大不了的。然而,对于任何其他类型的 C++ 实现,使用
std::thread
的 C++ 程序中可能会出现不需要的行为。

尽管如此,对于 pthreads 被认为是唯一的本机线程库的系统来说,这对我来说似乎很自然。 就其对线程敏感而言,您所描述的容器/沙箱应该按照本机线程进行操作。 如果这导致使用不同线程方案的应用程序出现问题,那么您可以合理地(根据我的说法)说这是其他人的问题。

© www.soinside.com 2019 - 2024. All rights reserved.