线程本地存储GCC编译器 [英] Thread local storage GCC Compiler

查看:128
本文介绍了线程本地存储GCC编译器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 配置为:../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 
线程模型:posix
gcc版本4.6.1(Ubuntu / Linaro 4.6.1-9ubuntu3)

我使用标志-lpthread来编译。
但编译器抱怨:错误:为'my_id'指定的存储类

解决方案

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



完成此操作的唯一有效方法是使变量 static - 原因是它导致变量存储在线程本地存储池而不是堆栈中。



例如在全球范围内:

  __ thread int my_id; 

可以工作,因为变量不在结构中。它可以自动放置到线程本地存储池中。



为一个结构体,如下所示:

  struct xx {
__thread int my_id;
};

将不起作用,因为变量可能在堆栈中结束,所以您需要使用:

  struct xx {
static __thread int my_id;
};

这会导致它被放置在线程本地存储池中,从而成为一个有效的线程变量。



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



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

I declare a variable __thread int my_id; Info of my platform and compiler:

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) 

I use flag -lpthread to compile. But Compiler complains: error: storage class specified for 'my_id'.

解决方案

You've declared thread local storage for a variable. This kind of storage for a variable cannot be declared as existing on the stack. Making it part of a struct/class implicitly permits it to be on the stack.

The only effective way to accomplish this is to make the variable static - the reason for this is that it causes the variable to be stored in the thread local storage pool instead of on the stack.

e.g. at the global scope:

__thread int my_id;

will work, as the variable is not in a structure. It can automatically be placed into the thread local storage pool.

for a structure, the following:

struct xx {
    __thread int my_id;
};

will not work, as the variable can end up on the stack, so you need to use:

struct xx {
    static __thread int my_id;
};

which causes it to be placed in the thread local storage pool, and thus be a valid thread variable.

Note: I'd previously described the variable as being on the heap. This is strictly speaking incorrect - the variable is taken from a per-thread block of memory that is allocated at thread creation time; I've renamed the term to the 'thread local storage' pool. This pool is of a platform specific size, and can be filled up if you have too many separate __thread variables.

The Wikipedia entry on Thread Local Storage explains this in good detail (including some gotchas).

这篇关于线程本地存储GCC编译器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆