线程本地存储GCC编译器

use*_*724 4 ubuntu multithreading gcc

我宣布一个变量__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) 
Run Code Online (Sandbox Code Playgroud)

我使用标志-lpthread进行编译.但编译抱怨:error: storage class specified for 'my_id'.

Pet*_*esh 13

您已为变量声明了线程本地存储.变量的这种存储不能声明为堆栈上存在.使其成为struct/class的一部分隐式地允许它在堆栈上.

实现此目的的唯一有效方法是创建变量static- 这是因为它导致变量存储在线程本地存储池而不是堆栈中.

例如,在全球范围内:

__thread int my_id;
Run Code Online (Sandbox Code Playgroud)

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

对于结构,以下内容:

struct xx {
    __thread int my_id;
};
Run Code Online (Sandbox Code Playgroud)

将无法工作,因为变量可以最终在堆栈上,所以你需要使用:

struct xx {
    static __thread int my_id;
};
Run Code Online (Sandbox Code Playgroud)

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

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

线程本地存储上维基百科条目详细解释了这一点(包括一些陷阱).