我试图在这个小程序中使用__thread而没有运气。不知道ndk 10c clang 3.4 / 3.5是否支持此TLS?使用ndk gcc 4.8 / 4.9和本地clang / gcc编译器编译相同的程序。
这是程序和编译行 -
__thread int counter;
int main () { counter=20; return 0; }
[armeabi] Compile++ thumb: test <= test.cpp
/Users/padlar/android/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/darwin-x86/bin/clang++ -MMD -MP -MF ./obj/local/armeabi/objs/test/test.o.d -gcc-toolchain /Users/padlar/android/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86 -fpic -ffunction-sections -funwind-tables -fstack-protector -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -target armv5te-none-linux-androideabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -I/Users/padlar/android/android-ndk-r10c/sources/cxx-stl/stlport/stlport -I/Users/padlar/android/android-ndk-r10c/sources/cxx-stl//gabi++/include -Ijni -DANDROID -Wa,--noexecstack -Wformat -Werror=format-security -fPIE -frtti -I/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/include -c jni/test.cpp -o ./obj/local/armeabi/objs/test/test.o
[armeabi] Executable : test
/Users/padlar/android/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/darwin-x86/bin/clang++ -Wl,--gc-sections -Wl,-z,nocopyreloc --sysroot=/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm -Wl,-rpath-link=/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib -Wl,-rpath-link=./obj/local/armeabi ./obj/local/armeabi/objs/test/test.o /Users/padlar/android/android-ndk-r10c/sources/cxx-stl/stlport/libs/armeabi/thumb/libstlport_static.a -lgcc -gcc-toolchain /Users/padlar/android/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86 -no-canonical-prefixes -target armv5te-none-linux-androideabi -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie -L/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib -llog -lc -lm -o ./obj/local/armeabi/test
jni/test.cpp:2: error: undefined reference to '__aeabi_read_tp'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [obj/local/armeabi/test] Error 1
ndk-which objdump
-S obj / local / armeabi / objs / test / test.o
obj/local/armeabi/objs/test/test.o: file format elf32-littlearm
Disassembly of section .text.main:
00000000 <main>:
__thread int counter;
int main () { counter=20; return 0; }
0: b580 push {r7, lr}
2: 4904 ldr r1, [pc, #16] ; (14 <main+0x14>)
4: f7ff fffe bl 0 <__aeabi_read_tp>
8: 1840 adds r0, r0, r1
a: 2114 movs r1, #20
c: 6001 str r1, [r0, #0]
e: 2000 movs r0, #0
10: bd80 pop {r7, pc}
12: 46c0 nop ; (mov r8, r8)
14: 00000000 .word 0x00000000
gcc4.6解析同一个程序
ndk-which objdump
-S obj / local / armeabi / objs / test / test.o
obj/local/armeabi/objs/test/test.o: file format elf32-littlearm
Disassembly of section .text.startup.main:
00000000 <main>:
__thread int counter;
int main () { counter=20; return 0; }
0: b508 push {r3, lr}
2: 4804 ldr r0, [pc, #16] ; (14 <main+0x14>)
4: 4478 add r0, pc
6: f7ff fffe bl 0 <__emutls_get_address>
a: 2314 movs r3, #20
c: 6003 str r3, [r0, #0]
e: 2000 movs r0, #0
10: bd08 pop {r3, pc}
12: 46c0 nop ; (mov r8, r8)
14: 0000000c .word 0x0000000c
答案 0 :(得分:3)
__thread
样式TLS(类似于C ++ 11样式thread_local
)(尽管我们正在努力)。目前,您必须使用pthread_getspecific
和pthread_setspecific
。
编辑:从NDK r12开始,Clang支持模拟TLS。虽然上述技术仍然是正确的(设备上的链接器不支持此功能),但编译器可以代表您使用pthread调用替换内置TLS支持。
注意:对于具有普通析构函数的对象,Android仍然只支持thread_local
直到r14。请参阅有关https://github.com/android-ndk/ndk/issues/156#issuecomment-231878690和https://github.com/android-ndk/ndk/issues/216的讨论。
答案 1 :(得分:0)
首先,您应该避免使用__thread,因为它可能无法移植。
以下是gnu gcc在此处所说的https://gcc.gnu.org/onlinedocs/gcc-4.8.3/gcc/Thread-Local.html:
GCC用于实现此功能的运行时模型源自IA-64处理器特定的ABI,但此后也已迁移到其他处理器。它需要链接器(ld),动态链接器(ld.so)和系统库(libc.so和libpthread.so)的大量支持,因此无处不在。
来自wikipédiahttp://en.wikipedia.org/wiki/Thread-local_storage#C.2B.2B:
C ++ 0x引入了thread_local关键字。除此之外,各种C ++编译器实现提供了声明线程局部变量的特定方法:
Sun Studio C/C++, IBM XL C/C++, GNU C and Intel C/C++ (Linux systems) use the syntax:
__thread int number;
Visual C++, Intel C/C++ (Windows systems), Borland C++ Builder and Digital Mars C++ use the syntax:
__declspec(thread) int number;
Borland C++ Builder also supports the syntax:
int __thread number;
因此它可以与thread_local
关键字