简体   繁体   English

gcc:编译为BSS的线程局部变量

[英]gcc: Thread-local variable compiled as BSS

I am new to and testing the thread-local storage (TLS) class with gcc (version 4.8.2) on my Ubuntu 14.04 computer with i686/32 bit architecture. 我是新手,并在我的Ubuntu 14.04计算机上使用i686 / 32位架构测试带有gcc (版本4.8.2)的线程本地存储 (TLS)类。

In trying to find out whether the __thread keyword has the desired effect, I compile this minimalistic test program with gcc test.c (no errors or warnings): 在试图找出__thread关键字是否具有所需效果时,我使用gcc test.c编译这个简约测试程序(没有错误或警告):

#include <stdio.h>

__thread int i;

int main() {
  i = 7;
  printf("%d\n",i);
}

and use the tool nm to check the storage class of the symbol i in the object code: 并使用工具nm检查目标代码中符号i的存储类:

nm a.out | grep ' i'

The result is 结果是

00000000 B i

which means that i is treated as a common global uninitialized variable (stored in the BSS section). 这意味着i被视为一个共同的全局未初始化变量(存储在BSS部分)。 According to man nm , thread local storage variables are denoted by the letter L , not B . 根据man nm ,线程局部存储变量用字母L表示,而不是B

What's wrong here? 这有什么不对?

Is this an nm problem or a real problem? 这是一个nm问题还是一个真正的问题?

There's no problem, it's just the way nm(1) writes output. 没问题,只是nm(1)写输出的方式。

nm(1) 's default output format (and information) is different among platforms (for example the manpage for nm(1) in my Linux desktop doesn't even mention L for thread-local storage). nm(1)的默认输出格式(和信息)在平台之间是不同的(例如,我的Linux桌面中的nm(1)的联机帮助页甚至没有提到L用于线程本地存储)。

However, if you enable SysV output format with -fs , you get a more verbose output: 但是,如果使用-fs启用S​​ysV输出格式,则会得到更详细的输出:

$ nm -fs a.out
Symbols from a.out:

Name                  Value           Class        Type         Size             Line  Section

...

i                   |0000000000000000|   B  |               TLS|0000000000000004|     |.tbss
...

As you can see, using this output format i is identified as being thread local under the column Type , and it lives in .tbss . 正如您所看到的,使用此输出格式, i在列Type下被标识为本地线程,并且它位于.tbss

If the manpage for your distribution mentions the L flag for thread-local storage and you don't see it in the default output format, I'd say it's a bug in nm(1) . 如果您的发行版的联机帮助页提到了L标志用于线程本地存储,并且您没有以默认输出格式看到它,我会说这是nm(1)的错误。

Your code is too minimal. 你的代码太小了。 The number of threads won't be known until runtime, so the variable that you see in the executable is the variable that main will use. 直到运行时才会知道线程数,因此您在可执行文件中看到的变量是main将使用的变量。 Additional copies of the variable will be allocated when additional threads are created. 创建其他线程时,将分配变量的其他副本。

Here's a minimal program that demonstrates thread variables. 这是一个演示线程变量的最小程序。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

__thread int i;

void *foo( void *args )
{
    i = 8;
    printf( "foo: %d\n", i );
    return NULL;
}

int main( void )
{
    i = 7;
    printf( "main:%d\n", i );

    pthread_t pid;
    if ( pthread_create( &pid, NULL, foo, NULL ) != 0 )
        exit( 1 );

    pthread_join( pid, NULL );
    printf( "main:%d\n", i );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM