在使用errno
时,我曾读过
重要的是要包含
errno.h
,而不是提供自己的extern int errno
,因为errno
是在线程安全中实现的 这种方式不仅仅是一个简单的全球int
。
线程安全方式如何影响#include
和extern
之间的差异?
答案 0 :(得分:4)
重要的不是extern vs #include
errno在标题中定义为
int* _errno(void);
#define errno (*_errno())
每个线程在自己的地址空间中都有自己的错误
答案 1 :(得分:3)
在POSIX.1中,errno被定义为外部全局变量。但是这个 定义在多线程环境中是不可接受的,因为它 使用会导致不确定的结果。问题是两个还是 更多线程可能会遇到错误,所有错误都会导致相同的错误 组。在这种情况下,线程可能最终检查错误 在它已经被另一个线程更新之后。
为了规避由此产生的不确定性,POSIX.1c重新定义了错误 作为可以访问每线程错误号的服务,如下所示 (ISO / IEC 9945:1-1996,§2.4):
某些函数可能会在通过符号errno访问的变量中提供错误编号。符号errno的定义包括 标题,由C标准指定...对于每个线程 在一个过程中,errno的值不受功能的影响 其他线程对errno的调用或赋值。
此外,所有POSIX.1c函数都避免使用errno,而是 直接返回错误号作为函数返回值,用a 返回值为零表示未检测到错误。这个 事实上,策略是在POSIX范围内对所有新策略进行跟踪 功能
答案 2 :(得分:2)
引用的文档警告您,您不应该假设 errno
被实现为
extern int errno;
<{1>}标题中的,就是全部。
显然,包含文件中可能包含<errno.h>
以外的内容;在这种情况下,实现者采取预防措施使extern
以线程安全的方式运行,但这是一个不必要的细节。真正必须知道的是你必须包括errno
。
如果您对细节非常好奇,请在编辑器中调出errno.h
,然后查看。但是,您需要记住,其他系统上的实现可能(通常也会)不同。
答案 3 :(得分:0)
至少在mysystem中,它被定义为#define errno (*__error())
,即它被计算为error
,它返回指向正确结果的指针。通过这种方式,您可以实现线程安全errno
。