【问题标题】:Using __thread in c99在 c99 中使用 __thread
【发布时间】:2011-07-29 06:24:15
【问题描述】:

我想使用 __thread 存储类将一些变量定义为线程特定的。但是三个问题让我犹豫了:

  1. 真的是c99的标准吗?或者更重要的是,编译器支持有多好?
  2. 是否会在每个线程中初始化变量?
  3. 非多线程程序是否将它们视为普通旧全局程序?

【问题讨论】:

  • 作为对收到的答案的附加,线程本地存储计划用于即将推出的标准 C1x。

标签: c multithreading c99


【解决方案1】:

回答您的具体问题:

  1. 不,它不是 C99 的一部分。您不会在 n1256.pdf (C99+TC1/2/3) 或原始 C99 标准的任何地方找到它。
  2. 是的,__thread 变量从每个新线程中的初始化值开始。
  3. 从程序行为的角度来看,线程局部存储类变量的行为与非多线程程序中的普通全局变量几乎相同。但是,它们确实会产生更多的运行时成本(内存和启动时间),并且可能存在对线程局部变量的大小和数量的限制问题。所有这一切都相当复杂,并且取决于您的程序是静态链接还是动态链接以及变量是驻留在主程序还是共享库中......

在我看来,除了实现 C/POSIX(例如errno 等)之外,线程本地存储类实际上并不是很有用。这几乎是避免以上下文指针或类似形式干净地传递必要状态的拐杖。您可能认为它对于绕过像qsort 这样不使用上下文指针的损坏接口很有用,但不幸的是,不能保证qsort 会在调用qsort 的同一线程中调用比较函数。它可能会破坏作业并在多个线程中运行它。对于大多数其他可以采用这种解决方法的接口也是如此。

【讨论】:

  • 当然线程本地数据总是有点麻烦,但这并不意味着您有时不需要破解。
  • 这里只想提一下 gnulib。它有一个线程本地存储(tls)模块,负责大多数平台/编译器。如果您正在编写 (L)GPL 软件,请考虑一下。没有它我不会开始编写独立于平台的代码 - 可以节省您的生命并减少头痛。
  • 嗯,gnulib 不能帮你写平台无关的软件。它可以帮助您编写具有硬编码平台相关hack 的软件,适用于一些N 古怪的遗留平台,仅此而已。这些 hack 中的大多数都不是线程安全的,并且还存在各种有问题的极端情况错误。
【解决方案2】:

您可能想阅读以下内容:

http://www.akkadia.org/drepper/tls.pdf

1) MSVC 不支持 C99。 GCC 确实如此,其他编译器尝试 GCC 兼容性。

编辑此处提供了对 __thread 的编译器支持细分:

http://chtekk.longitekk.com/index.php?/archives/2011/02/C8.html

2) 只有 C++ 支持初始化器并且它必须是常量。

3) 非多线程应用程序是单线程应用程序。

【讨论】:

  • 所以,对于 (1),答案是“不”;它不在 C99 标准中。
  • 它在 C99 编辑中被列为存储类说明符gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/…
  • @Steve-o:这并不意味着它与 C99 有任何关系。相反,该文档只是展示了如何修改 C99 以包含 __thread 关键字。即将推出的 C1x 预计将包括线程本地存储类,但它绝对不是 C99 的一部分。
猜你喜欢
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
相关资源
最近更新 更多