首先errno
是个全局变量,刚开始UNIX/Linux只有进程,这样多进程也是安全的。但是后来有了线程,线程间是可以共享全局变量的,这样errno
就线程不安全了。解决办法是线程实现TLS(Thread Local Storage),每个线程都有一个errno
变量。
errno is defined by the ISO C standard to be a modifiable lvalue of type int, and must not be explicitly declared; errno may be a macro. errno is thread-local; setting it in one thread does not affect its value in any other thread.
如uClibc里的定义./libc/misc/internals/errno.c
,glibc是csu/errno.c
。
__thread int errno;
这依赖编译器打开TLS特性,很多嵌入式编译链不一定打开。运行arm-linux-uclibcgnueabi-gcc -v
来检查,如果看到--enable-tls
就是编译链打开TLS特性,这样编译链支持__thread
或者thread_local
关键词。
如果是C库是可配置的,C库的TLS也要打开,如uClibc,查看include/bits/uClibc_config.h
文件,查找是否有下面选项:
#define __UCLIBC_HAS_TLS__ y
参考资料
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。