[英]Thread-safe singleton using atomic
只想知道atomic_flag = 1;
保持 myclass_st 分配线程安全与否。 (对不起,我的例子有这么多问题,所以我改了。)
myClass* myclass_st = nullptr;
std::atomic<int> atomic_flag;
std::mutex mtx; //err
myClass* get_instance() {
//std::unique_lock<std::mutex> lk(mtx);
if (myclass_st == nullptr) {
mtx.lock();
if (myclass_st == nullptr) {
myclass_st = new myClass();
atomic_flag = 1;
mtx.unlock(); //err
}
}
return myclass_st;
}
我知道我们可以在 c11 之后使用static
。
也许我应该像这样修改代码?
myClass* myclass_st = nullptr;
std::atomic<int> atomic_flag;
myClass* get_instance() {
if (atomic_flag.load() == 0) {
std::unique_guard<std::mutex> lk(mtx);
if (atomic_flag.load() == 0) {
myclass_st = new myClass();
atomic_flag = 1;
}
}
return myclass_st;
}
显示的代码不是线程保存的,因为std::mutex mtx;
每次都是新的 object。 std::mutex mtx;
必须是static so that it is the same mutex for each invocation of
但即便如此,手动锁定和解锁互斥锁在当前形式下也无效。
移动std::mutex mtx;
后编辑; 在 function 中,每次调用get_instance
的互斥锁都是相同的。 但它仍然不是线程保存。 多个线程可以通过第一个if (myclass_st == nullptr) {
myclass_st
为nullptr
的条件。 如果有例如超过三个线程通过第一个if
那么第一个调用lock
的线程将设置myclass_st
并释放它在互斥锁上的锁。 第二个调用lock
的线程不会释放它获得的锁,因此所有其他通过第一个if
的线程都被阻塞。
它必须是:
myClass* get_instance() {
mtx.lock();
if (myclass_st == nullptr) {
myclass_st = new myClass();
atomic_flag = 1;
}
mtx.unlock();
return myclass_st;
}
您通常不想手动锁定和解锁,而是使用具有自动存储持续时间(RAII 习惯用法)的锁守卫进行锁定,因为这样可以确保在离开get_instance
时始终释放互斥锁上的锁。
myClass* get_instance() {
std::lock_guard<std::mutex> lk(mtx);
if (myclass_st == nullptr) {
myclass_st = new myClass();
atomic_flag = 1;
}
return myclass_st;
}
编辑不,第一个和第二个示例都不是线程保存。 对于您展示的第二个示例, if (atomic_flag.load() == 0) { /**... **/ atomic_flag = 1;}
仍然可以由两个线程输入。 所以new myClass
仍然可以多次完成。
只想知道 atomic_flag = 1; 保持 myclass_st 分配线程安全与否。
不。
也许我应该像这样修改代码?
myClass* myclass_st = nullptr; std::atomic<int> atomic_flag; myClass* get_instance() { if (atomic_flag.load() == 0) { myclass_st = new myClass(); atomic_flag = 1; } return myclass_st; }
如果您打算让多个线程调用get_instance
,那么不会。
我猜你想要:
myClass* myclass_st = nullptr;
std::atomic<int> atomic_flag{0};
std::mutex mtx;
myClass* get_instance() {
if (atomic_flag == 0) {
std::unique_lock<std::mutex> lk(mtx);
if (myclass_st == nullptr) {
myclass_st = new myClass();
atomic_flag = 1;
}
}
return myclass_st;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.