errno 变量一直被用于调用系统函数时出错后,被赋上错误码的整数变量。
一直以来我们认为 errno 变量都被定义为进程上下文中的一个全局整数。在使用 errno 的时候,通常会使用 #include <errno.h>
将其包含进来。
诸位有没有想过,既然它是全局的,在多线程中会不会出问题?对此问题我想大家心中早有疑问,为此我们先做一个实验进行验证。
1. 程序清单
程序的目的很简单,就是在两个不同的线程中改写 errno 的值,另外采用了一个我们自定义的 mydata 变量进行对比。
1.1 代码
// errno.c
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
int mydata;
void* fun1() {
errno = 5;
mydata = 5;
sleep(1);
printf("fun1: errno = %d, mydata = %d\n", errno, mydata);
return NULL;
}
void* fun2() {
errno = 10;
mydata = 10;
sleep(1);
printf("fun2: errno = %d, mydata = %d\n", errno, mydata);
return NULL;
}
int main() {
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, fun1, NULL);
pthread_create(&tid2, NULL, fun2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
1.2 编译与运行
- 编译与运行
$ gcc errno.c -o errno -lpthread
$ ./errno
- 运行结果
图1 运行结果
1.3 结果分析
从图 1 中可以看到,自己定义的变量 mydata 由于多线程的原因,导致在 fun2 函数中打印的结果为 5. 同样是全局变量,为什么 errno 就没事?
至少上面的实验证明了 errno 变量是多线程安全的。此问题,我们在后面的文章中讨论。
2. 总结
- 知道 errno 变量是线程安全的