std::call_once
时间: 2023-12-13 08:04:23 浏览: 191
std::call_once是C++11中的一个线程库函数,用于保证一个函数只被执行一次。它需要传入一个std::once_flag类型的标志,用于标记函数是否已经被执行过。当多个线程同时调用std::call_once时,只有一个线程会执行函数,其他线程会被阻塞,直到函数执行完毕。这个函数通常用于初始化一些全局变量或者单例对象。
相关问题
详细讲解一下std::call_once
std::call_once是C++11标准库中的一个函数,用于保证一个函数只被调用一次。它的原型如下:
template <class Callable, class... Args>
void call_once(std::once_flag& flag, Callable&& func, Args&&... args);
其中,flag是一个std::once_flag类型的对象,用于标记函数是否已经被调用过;func是一个可调用对象,可以是函数指针、函数对象或者Lambda表达式;args是func的参数列表。
当第一次调用std::call_once时,它会执行func(args...),并将flag标记为已调用。后续调用std::call_once时,如果flag已经被标记为已调用,则不会再次执行func(args...),而是直接返回。
std::call_once的一个常见用途是在多线程环境下保证某个函数只被调用一次。例如,可以使用std::call_once来初始化一个全局变量:
std::once_flag flag;
int global_var;
void init_global_var() {
global_var = compute_value();
}
void foo() {
std::call_once(flag, init_global_var);
// 使用global_var
}
在第一次调用foo时,std::call_once会执行init_global_var,计算出global_var的值并将flag标记为已调用。后续调用foo时,std::call_once会直接返回,不会再次执行init_global_var。这样就保证了global_var只被初始化一次。
总之,std::call_once是一个非常有用的函数,可以帮助我们在多线程环境下保证某个函数只被调用一次。
使用 C++11 std::call_once 实现的懒汉单例使用 C++11 std::call_once 实现的懒汉单例,C++11 线程安全。
在 C++11 中,`std::call_once` 函数是一个线程安全的宏,它用于确保一个初始化函数只被执行一次。这对于实现懒汉式(Lazy Singleton)设计模式非常有用,即延迟创建单例对象直到第一次被请求。
懒汉单例的基本思想是在首次访问时动态地创建并返回唯一的实例,避免了全局变量带来的潜在风险,并且可以控制单例的生命周期。以下是使用 `std::call_once` 实现懒汉单例的一个示例:
```cpp
#include <mutex>
#include <memory>
class Singleton {
private:
static std::once_flag flag;
static std::shared_ptr<Singleton> instance;
protected:
Singleton() = default; // 防止通过构造函数直接创建实例
public:
static std::shared_ptr<Singleton>& getInstance() {
std::call_once(flag, [] {
if (!instance) {
instance = std::make_shared<Singleton>();
}
});
return instance;
}
// 其他成员函数...
};
std::once_flag Singleton::flag;
std::shared_ptr<Singleton> Singleton::instance = nullptr;
```
在这个例子中,`getInstance()` 函数会保证在第一次被调用时,`instance` 被正确初始化。如果之后再次调用,`call_once` 将不会执行内部的初始化代码,因为已经完成了一次。
阅读全文