结论是:两者都是线程安全。
1. getlasterror
参考微软官方文档说明如下:
GetLastError function (errhandlingapi.h) Retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code. ... _Post_equals_last_error_ DWORD GetLastError(); Parameters This function has no parameters. ... Return value The return value is the calling thread's last-error code.
直接说明last-error code变量是线程安全的。
2. errno
参考源码:
# ifndef __ASSEMBLER__ /* Function to get address of global `errno' variable. */ extern int *__errno_location (void) __THROW __attribute__ ((__const__)); # if !defined _LIBC || defined _LIBC_REENTRANT /* When using threads, errno is a per-thread value. */ # define errno (*__errno_location ()) # endif # endif /* !__ASSEMBLER__ */ #endif /* _ERRNO_H */
注释写道,当使用了多线程时(不定义宏_LIBC 或 定义宏_LIBC_REENTRANT),errno是一个线程内变量。这里errno宏代表__errno_location 函数的返回值
在http://www.unix.org/whitepapers/reentrant.html中也发现到:
Redefinition of errno In POSIX.1, errno is defined as an external global variable. But this definition is unacceptable in a multithreaded environment, because its use can result in nondeterministic results. The problem is that two or more threads can encounter errors, all causing the same errno to be set. Under these circumstances, a thread might end up checking errno after it has already been updated by another thread. To circumvent the resulting nondeterminism, POSIX.1c redefines errno as a service that can access the per-thread error number as follows (ISO/IEC 9945:1-1996, §2.4): Some functions may provide the error number in a variable accessed through the symbol errno. The symbol errno is defined by including the header <errno.h>, as specified by the C Standard ... For each thread of a process, the value of errno shall not be affected by function calls or assignments to errno by other threads. In addition, all POSIX.1c functions avoid using errno and, instead, return the error number directly as the function return value, with a return value of zero indicating that no error was detected. This strategy is, in fact, being followed on a POSIX-wide basis for all new functions. Footnotes 1. In POSIX.1c, a "reentrant function" is defined as a "function whose effect, when called by two or more threads, is guaranteed to be as if the threads each executed the function one after another in an undefined order, even if the actual execution is interleaved" (ISO/IEC 9945:1-1996, §2.2.2). 2. It should be noted that the flockfile() function, like the pthread_mutex_lock() function, can lead to priority inversion. The application developer should take this into account when designing an application and analyzing its performance.
参考https://blog.csdn.net/weixin_35695879/article/details/89530417:
extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec"))); int * __errno_location (void) { return &__libc_errno; }
印证了errno是线程安全的
p.s.现在使用到的库函数基本上都是支持POSIX标准的:https://blog.csdn.net/lwwl12/article/details/88763968?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param
Linux作为一个从头开始研制的新操作系统,逐渐发展起来以后为了尽可能获得大量应用软件支持,也明智地选择了用POSIX作为API设计的标准。
linux系统基本都支持POSIX,所以在linux之间,c++程序的移植性是得到保证的
参考:https://www.cnblogs.com/zhangyachen/p/10054689.html