加锁
一般来说我们对于一些延迟初始化的资源操作如下:
std::shared_ptr<some_resource> resource_ptr;
void foo()
{
if (!resource_ptr) {
resource_ptr.reset(new some_resources); // 及时初始化
}
resource_ptr->do_sth();
}
如果有多个线程执行foo函数,那么可能会出现线程不安全的情况。
所以可以这样改写,利用互斥实现线程安全的延迟初始化
std::shared_ptr<some_resource> resource_ptr;
std::mutex resource_mtx;
void foo()
{
std::unique_lock<std::mutex> lock(resource_mtx);
if (!resource_ptr) {
resource_ptr.reset(new some_resources); // 及时初始化
}
lock.unlock();
resource_ptr->do_sth();
}
std::call_once可以保证所有线程共同调用时的线程安全且唯一完成。
我们来改写一下上面的代码:
std::shared_ptr<some_resource> resource_ptr;
std::once_flag resource_flag;
void init_resouce() {
resource_ptr.reset(new some_resources); // 及时初始化
}
void foo()
{
std::call_once(resource_flag, init_resouce);
resource_ptr->do_sth();
}
class X {
private:
connection_info connection_details;
connection_handle connection;
std::once_flag connection_init_flag;
void open_connection() {
connection = connection_manager.open(connection_details);
}
public:
X(connection_info const& connection_details_) : connection_details(connection_details_) {}
void send_data(data_packet const& data) {
std::call_once(connection_init_flag, &X::open_connection, this);
connection.send_data(data);
}
data_packet receive_data() {
std::call_once(connection_init_flag, &X::open_connection, this);
return connection.receive_data();
}
};
C++11之后可以使用static变量进行声明。保证控制流程中初始化只会在某一个线程中单独发生
No comments yet.