- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在我的代码中使用 std::call_once
只初始化一些共享变量一次。调用代码位于由多个线程触发的回调中。我有兴趣知道,因为我在文档中找不到它,所以 std::call_once
是否本质上是阻塞的,就好像有一个 std::lock_guard
反而?在实践中看起来是这样的。
例如,以下将在调用任何 print()
之前打印 "Done"
:
#include <future>
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void print()
{
for(int i=0;i<10;i++)
{
std::cout << "Hi, my name is " << std::this_thread::get_id()
<< ", what?" << std::endl;
}
}
void do_once()
{
std::cout << "sleeping for a while..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "Done" << std::endl;
}
void work()
{
std::call_once(flag, [](){ do_once(); });
print();
}
int main()
{
auto handle1 = std::async(std::launch::async, work);
auto handle2 = std::async(std::launch::async, work);
auto handle3 = std::async(std::launch::async, work);
auto handle4 = std::async(std::launch::async, work);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
我假设这确实是这种情况(因为我不知道如何以其他方式实现它),但是这种行为是否得到保证,或者是否可以有一个编译器决定 std::call_once
确实会被调用一次但允许其他线程继续并忽略此调用?
最佳答案
是std::call_once
是一个阻塞调用。从 [thread.once.callonce] 我们有
Effects: An execution of call_once that does not call its
func
is a passive execution. An execution of call_once that calls itsfunc
is an active execution. An active execution shall callINVOKE (DECAY_COPY ( std::forward<Callable>(func)), DECAY_COPY (std::forward<Args>(args))...)
. If such a call to func throws an exception the execution is exceptional, otherwise it is returning. An exceptional execution shall propagate the exception to the caller of call_once. Among all executions ofcall_once
for any givenonce_flag
: at most one shall be a returning execution; if there is a returning execution, it shall be the last active execution; and there are passive executions only if there is a returning execution. [ Note: passive executions allow other threads to reliably observe the results produced by the earlier returning execution. —end note ]Synchronization: For any given
once_flag
: all active executions occur in a total order; completion of an active execution synchronizes with (1.10) the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions.
强调我的
这意味着所有对 call_once
的调用将等到函数传递给 call_once
完成。在您的情况下,这意味着 do_once()
必须在任何线程调用之前调用 print()
关于c++ - std::call_once 是阻塞调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43054677/
我正在尝试使用 call_once(...) 初始化一个函数。我的程序给我编译错误“std::once_flag::once_flag(const std::once_flag&)”:试图引用已删除的
boost::call_once 是如何实现的? 这个是否使用双重检查锁定模式? Qt 或 POCO 库中是否有任何等效的实现? 最佳答案 我偶然发现了这个老问题..4 年后,您的案例可能不再有趣,但
以下program尝试在构造函数中使用 call_once()。它是对Stroustrup在“CPL”,4中提供的示例的修改。 class X { private: static int dat
1) std::call_once A a; std::once_flag once; void f ( ) { call_once ( once, [ ] { a = A {....}; }
嗯,我在自己的项目中使用单例。最常用的单例实现可能是 Meyer 的单例以及使用 std::call_once 或 pthread_once 的单例实现。它们对于并行计算都是线程安全的 //Meyer
我已经测试了在多线程上下文中对变量使用 call_once() 并且行为符合预期。 但是,在多线程上下文中,我很难让 call_once() 与构造函数一起正常工作。 以下program已为此而写。它
我想知道 std::call_once 锁是否空闲。 There是使用互斥锁的 call_once 实现。但是我们为什么要使用互斥体呢?我尝试使用 atomic_bool 和 CAS 操作编写简单的实
给定来自 here 的代码: class lazy_init { mutable std::once_flag flag; mutable std::unique_ptr data;
std::call_once是线程安全的,但它也是可重入的吗? 我使用 VS2012(调试和发布)进行的测试表明,从单个线程递归调用 std::call_once 是可以的,但如果在单独的线程上进行调
std::call_once function ,在 C++11 中引入,确保可调用对象以线程安全的方式被恰好调用一次。 因为这可以通过其他方式实现 - 什么时候应该使用 std::call_once
对于非原子变量,std::call_once 会正常工作吗?考虑以下代码 std::once_flag once; int x; void init() { x = 10; } void f() {
如果我用 call_once 调用一个函数,如果它在完成执行前抛出异常,那么 once_flag 的值是多少? 最佳答案 once_flag状态未修改,因此下一次调用 call_once与相同once
我想使用 boost::call_once() 来实现线程安全的惰性构造然而,单例场景中,单例基类有许多派生类,因此 getInstance() 函数采用一个参数来确定要初始化哪个派生类。代码看起来像
我需要在我的模板化单例类中使用 std::call_once 但目前下面的示例代码没有编译: std::once_flag flag; class LifeTrackerHelper { public
我在我的代码中使用 std::call_once 只初始化一些共享变量一次。调用代码位于由多个线程触发的回调中。我有兴趣知道,因为我在文档中找不到它,所以 std::call_once 是否本质上是阻
前阵子写了一个函数,基于Unreal Engine 4's blueprint implementation , 调用一次可调用直到它被重置: template void DoOnce(Callabl
我正在尝试一个简单的例子来检查 std::call_once() 的行为.我尝试了以下代码,但没有做任何有用的工作。 class Test { private: std::string o
假设我有一个函数返回一个昂贵的对象,并且我希望它在访问该函数的返回值时只调用一次。 这是可以通过 std::once_flag 和 std::call_once 实现的,还是我需要使用 bool 标志
假设我有一个函数返回一个昂贵的对象,并且我希望它在访问该函数的返回值时只调用一次。 这是可以通过 std::once_flag 和 std::call_once 实现的,还是我需要使用 bool 标志
我试图从文档页面 https://en.cppreference.com/w/cpp/thread/call_once 运行示例但它不像预期的那样工作。它会无限卡住。我想知道为什么会发生这种情况,或者
我是一名优秀的程序员,十分优秀!