gpt4 book ai didi

c++ - 通过 std::shared_ptr::reset() 同步销毁

转载 作者:行者123 更新时间:2023-11-30 05:22:30 31 4
gpt4 key购买 nike

考虑以下模拟真实场景的简化程序,在该场景中,不同的用户可以对同一资源发出并发请求:

#include <thread>
#include <memory>
#include <mutex>
#include <iostream>

using namespace std;

struct T {
void op() { /* some stuff */ }
~T() noexcept { /* some stuff */ }
};

std::shared_ptr<T> t;
std::mutex mtx;
std::weak_ptr<T> w{t};
enum action { destroy, op};

void request(action a) {
if (a == action::destroy) {
lock_guard<mutex> lk{mtx};
t.reset();
std::cout << "*t certainly destroyed\n";
} else if (a == action::op) {
lock_guard<mutex> lk{mtx};
if (auto l = w.lock()) {
l->op();
}
}
}

int main() {
// At some point in time and different points in the program,
// two different users make two different concurrent requests
std::thread th1{request, destroy}; std::thread th2{request, op};

// ....
th2.join();
th1.join();
}

我不是在问这个程序在形式上是否正确——我认为是,但我从未见过这种保证通过智能指针共享的资源同步销毁的方法。我个人认为它很好并且有有效的用途。

但是,我想知道其他人是否也有同样的想法,以防万一,除了使用 unique_lock 和条件变量的经典同步以及引入修改(例如原子标志)之外,是否还有更优雅的替代方案) 到 T

如果我能以某种方式摆脱 mtx 就太理想了。

最佳答案

是的,没关系。 shared_ptr 中的引用计数是原子的,锁定的拷贝在操作期间保持在范围内,因此对象不能在操作期间被销毁。

在这种情况下,互斥锁实际上并没有保护 T 的生命周期,而是对 op() 的排序调用。和破坏。如果您不介意对 op() 的多个并发调用, 或者销毁时间不确定(即在最后一次运行 op() 完成后),那么你可以取消它,因为 std::shared_ptr<>::reset()std::weak_ptr<>::lock()都是线程安全的。

但是,我会建议谨慎,因为作者明确表示要调用 op()待连载。

关于c++ - 通过 std::shared_ptr<T>::reset() 同步销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626291/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com