errno是线程安全的吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (67)

errno.h这个变量被声明为extern int errno;

它是否是线程安全的?如果不是的话有什么替代吗?

我在x86架构上使用带有gcc的linux。

提问于
用户回答回答于

是的,它是线程安全的。在Linux上,全局errno变量是线程特定的。POSIX要求errno是线程安全的。

请参阅http://www.unix.org/whitepapers/reentrant.html

在POSIX.1中,errno被定义为一个外部全局变量。但是这个定义在多线程环境中是不可接受的,因为它的使用会导致不确定的结果。问题是两个或多个线程可能会遇到错误,所有错误都会导致设置相同的错误号。在这些情况下,一个线程可能最终在另一个线程更新之后检查errno。 为了规避由此产生的不确定性,POSIX.1c将errno重新定义为可以访问每个线程错误号的服务(ISO / IEC 9945:1-1996,§2.4): 某些函数可能会在通过符号errno访问的变量中提供错误编号。符号errno通过包含头文件来定义,如C标准所指定的...对于进程的每个线程,errno的值不应受到函数调用或其他线程对errno的赋值的影响。

另请参阅http://linux.die.net/man/3/errno

errno是线程本地的; 将它设置在一个线程中不会影响其在任何其他线程中的值。

用户回答回答于

是安全的


Errno不再是一个简单的变量了,它在后台非常复杂,特别是它是线程安全的。

$ man 3 errno:

ERRNO(3)                   Linux Programmer’s Manual                  ERRNO(3)

NAME
       errno - number of last error

SYNOPSIS
       #include <errno.h>

DESCRIPTION

      ...
       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.

或者:

$ cat > test.c
#include <errno.h>
f() { g(errno); }
$ cc -E test.c | grep ^f
f() { g((*__errno_location ())); }
$ 

扫码关注云+社区