我遇到了由此行为导致的错误:
#include <mutex>
std::once_flag onceFlag;
void get() {
std::call_once(onceFlag, [](){ get(); });
}
int main(int argc, char* argv[]) {
get();
return 0;
}
另一种方式是:
#include <mutex>
std::once_flag onceFlag;
int main(int argc, char* argv[]) {
std::call_once(onceFlag,
[](){
std::call_once(onceFlag,
[](){}
);
}
);
return 0;
}
根据我在cppreference(http://en.cppreference.com/w/cpp/thread/call_once)上所读到的内容,这是可以预料的,因为第一次调用std :: call_once还没有完成执行:
在上述之前,组中没有调用返回 成功完成所选功能的执行,即 不会通过例外退出。
为什么上述要求?在调用函数之前是否可以设置once_flag,如果抛出异常则重置?
答案 0 :(得分:2)
为什么上述要求?之前不能设置once_flag 调用该函数,如果抛出异常则重置?
没有。在您的提案中,once_flag
将被设置,然后在发生任何故障时重置。这可能会造成竞争条件。考虑具有2个线程的这种情况:th1
和th2
。两者都在做一些任务,需要完成一次。线程依赖once_flag
在您的提案中工作。 th1
内部功能由once_flag
保护。 th2
正在检查once_flag
条件并停止执行,因为它的pov任务已完成。在任务执行期间,th1
抛出异常,从th1
pov它很好,因为其他一些工作人员将完成执行。任务永远不会完成,因为th1
失败并且once_flag
未设置,但th2
已完成,因为once_flag
已设置,并且它认为任务已完成。
根据当前的要求,不会发生这种不一致。