每个线程 C++ 保护以防止重入函数调用

per thread c++ guard to prevent re-entrant function calls

本文关键字:函数调用 线程 C++ 保护      更新时间:2023-10-16

我有一个函数,可以调用可能失败的注册表并打印失败原因。

这个函数也可以直接或间接地从专用的内置打印函数的上下文中调用,我希望在这种情况下避免打印原因,以避免无休止的递归。

我可以使用thread_local来定义每个线程标志以避免从此函数调用打印函数,但我想这是一个相当普遍的问题,所以我正在寻找这个保护或任何其他调试良好的代码std实现。

下面是一个刚刚用来表达问题的示例。 每个打印函数都带有日志级别,并与驻留在注册表中的当前日志级别阈值进行比较。如果低于阈值,则函数返回而不打印。但是,为了获得阈值,可以进行额外的打印,因此我想创建一个保护,以防止打印getPrintLevelFromRegistry如果从print调用


int getPrintLevelFromRegistry() {
int value = 0;
DWORD res = RegGetValueW("//Software//...//logLevel" , &value);
if (res != ERROR_SUCCESS) {
print("couldn't find registry key");
return 0;
}
return value;
}
void print(const char * text, int printLoglevel) {
if (printLogLevel < getPrintLevelFromRegistry()) {
return;
}
// do the print itself
...
}

谢谢!

问题的根源在于您正在尝试让日志记录代码本身记录。 与其考虑一些复杂的防护,不如考虑这样一个事实,即您确实不需要记录注册表读取。 只需让它返回默认值并将错误记录到控制台即可。

int getPrintLevelFromRegistry() {
int value = 0;
DWORD res = RegGetValueW("//Software//...//logLevel" , &value);
if (res != ERROR_SUCCESS) {
OutputDebugStringA("getPrintLevelFromRegistry: Can't read from registryrn");
}
return value;
}

此外,可以从注册表中读取每个日志语句,但这是冗余且不必要的。

更好:

int getPrintLevelFromRegistry() {
static std::atomic<int> cachedValue(-1);
int value = cachedValue;
if (value == -1) {
DWORD res = RegGetValueW("//Software//...//logLevel" , &value);
if (res == ERROR_SUCCESS) {
cachedValue = value;
}
}
return value;
}