gpt4 book ai didi

c - 如果#define 替换 errno 符号,线程安全的 errno 是如何初始化的?

转载 作者:太空宇宙 更新时间:2023-11-04 02:08:22 26 4
gpt4 key购买 nike

我试图了解 glibc 如何在预处理器不替换 errno 符号的情况下初始化 errno

我首先尝试自己基于csu/errno-loc.c实现了一个简单的版本和 csu/errno.c :

myerrno.h

#ifndef MYERRNO_H
#define MYERRNO_H

extern int *myerrno_location(void);
#define myerrno (*myerrno_location())

#endif

myerrno.c

#include "myerrno.h"

static int myerrno = 0;

int *myerrno_location(void){
return &myerrno;
}

但是,当我尝试编译时收到以下错误消息:

myerrno.c:3:1: error: function ‘myerrno_location’ is initialized like a variable
myerrno.c:3:12: error: static declaration of ‘myerrno_location’ follows non-static declaration
myerrno.h:4:13: note: previous declaration of ‘myerrno_location’ was here

我可以看出预处理器在第 3 行遇到 myerrno 时正在替换 (*myerrno_location(void)) —— 这自然是预期的行为。

我不明白为什么这不是 glibc 的问题。 errno 的线程安全实现如何在不重命名静态 errno 变量的情况下解决这个预处理器替换问题?

最佳答案

解决问题就像更改静态变量的名称一样简单。

static int myerrno_variable = 0;

int *myerrno_location(void){
return &myerrno_variable;
}

请注意,您的版本仍然不是线程安全的,因为所有线程都在访问相同的 myerrno_variable。一个真正的实现会返回一个线程特定的内存位置。在 GCC 中,有一个扩展提供了 __thread存储类。 C.11 提供了它自己的称为 thread_local 的版本,但它仅在实现提供线程支持时可用(可以通过查看是否定义了 __STDC_NO_THREADS__ 来检查)或不)。

static __thread int myerrno_variable_gcc;      /* if using GCC */
static thread_local int my_errno_variable_c11; /* if __STD_NO_THREADS__ isn't defined */

在没有线程局部特征的 POSIX 系统上,实现可以使用 pthread_getspecific() 获取指向为每个线程分配的线程特定数据的指针,并使用 pthread_setspecific( )。参见 the manual获取更多信息。

关于c - 如果#define 替换 errno 符号,线程安全的 errno 是如何初始化的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18025995/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com