【问题标题】:Thread local storage GCC Compiler线程本地存储 GCC 编译器
【发布时间】:2012-10-22 08:31:52
【问题描述】:

我声明了一个变量__thread int my_id; 我的平台和编译器信息:

Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) 

我使用标志 -lpthread 来编译。 但是编译器抱怨:error: storage class specified for 'my_id'.

【问题讨论】:

  • 你试过什么?
  • 请在头文件中显示原始声明及其在源代码中的列表。

标签: multithreading gcc ubuntu


【解决方案1】:

您已经为变量声明了线程本地存储。变量的这种存储方式不能声明为存在于堆栈中。使其成为结构/类的一部分隐式允许它在堆栈上。

实现这一点的唯一有效方法是使变量static - 这样做的原因是它导致变量存储在线程本地存储池而不是堆栈中。

例如在全球范围内:

__thread int my_id;

会起作用,因为变量不在结构中。可以自动放入线程本地存储池中。

对于结构,如下:

struct xx {
    __thread int my_id;
};

不会起作用,因为变量最终会在堆栈上,所以你需要使用:

struct xx {
    static __thread int my_id;
};

这导致它被放置在线程本地存储池中,因此是一个有效的线程变量。

注意:我之前将变量描述为在堆上。这严格来说是不正确的——变量取自在线程创建时分配的每个线程的内存块;我已将该术语重命名为“线程本地存储”池。此池具有特定于平台的大小,如果您有太多单独的 __thread 变量,可以将其填满。

Wikipedia entry on Thread Local Storage 详细解释了这一点(包括一些陷阱)。

【讨论】:

  • 只是一点点:不完全是堆存储。它是大小固定的全局存储,并作为可执行文件或库的一部分加载和初始化。堆存储是动态的。
  • 真;我会尽量整理答案
  • 感谢您的解释。
【解决方案2】:

您需要将变量声明为静态。

【讨论】:

    猜你喜欢
    • 2016-05-17
    • 2020-02-20
    • 2011-04-13
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多