MSVC错误的线程安全
在MSVC线程安全上是errno
吗?
根据这个问题的答案,POSIX要求errno
是线程安全的。 但MSVC可能不符合POSIX, MSDN也没有说明线程安全。 MSDN矛盾提到errno
被声明为extern int errno;
,还作为#define errno (*_errno())
虽然MSVC绝对不符合POSIX,但是errno
是以线程安全的方式在MSVC运行时(至少从MSVC2008开始)实现的。
尽管文档声明它是extern int errno
但它实际上是作为#define
实现的,它允许强制执行线程安全的函数。 如果在反汇编窗口中单步执行此function,则很明显使用了线程本地存储。
可悲的是,我不能指出任何证实这一点的官方文件,但这就是生活!
我无法在MSDN网站上的任何地方找到这个讨论的地方。 但是,许多返回静态缓冲区的函数在MSVC中已经是线程安全的(即它们返回指向线程本地缓冲区的指针)。 因此,如果errno不是线程安全的话会令人惊讶。
MSVC头文件都有这个定义:
#ifndef _CRT_ERRNO_DEFINED #define _CRT_ERRNO_DEFINED _CRTIMP extern int * __cdecl _errno(void); #define errno (*_errno()) errno_t __cdecl _set_errno(_In_ int _Value); errno_t __cdecl _get_errno(_Out_ int * _Value); #endif /* _CRT_ERRNO_DEFINED */
一个小的测试程序显示设置errno的2个线程至少不会影响彼此。 所以我认为假设errno是线程安全的是安全的(尽管如果链接到单线程CRT可能不是这样)