如何安全地销毁经常被两个不同线程访问的对象
How to safely destroy an object, that is frequently accessed by two different threads?
我目前遇到了一个问题,即必须释放经常被两个不同线程访问的对象(实例(。对我来说,两个线程中的哪一个正在破坏实例并不重要,但我更喜欢一个,它也创建了它,尽管我认为这根本不重要。
因此,在应该销毁对象的线程检测到它应该被删除的情况下,并且在调用析构函数时,另一个线程正在访问该对象的成员(函数(,可能会发生某种运行时错误。
我对这个主题做了一些研究,但我可以弄清楚人们说:"为什么要删除仍然需要存在的对象"。但就我而言,在一个线程正在执行的代码段决定销毁它之后,应该不再需要它。
我希望得到一个答案,比如对一本涵盖这个主题的好书或文章的提示,但请随意写下你将如何解决这个问题。
您需要双重间接寻址来管理对数据的并发访问:
class Object {
public;
class Data {
int get_value() const;
void set_value(int);
};
class Guard {
public:
Guard(Nutex& mutex, Data* data)
: data(data)
{
if( ! data) throw std::runtime_error("No Data");
mutex.lock();
}
~Guard()
{
mutex.unlock();
}
Data& data() { return *m_data; }
private:
Data* data;
};
class ConstGuard {
public:
ConstGuard(Mutex& mutex, const Data* data)
: data(data)
{
if( ! data) throw std::runtime_error("No Data");
mutex.lock();
}
~ConstGuard()
{
mutex.unlock();
}
const Data& data() const { return *m_data; }
private:
const Data* data;
};
private:
friend std::shared_ptr<Object> make_object(const Data&);
Object(const Data& data)
: data(new Data(data))
{}
public:
~Object()
{
delete data;
}
/// Self destruction.
void dispose() {
Guard guard(get());
delete data;
data = 0;
}
// For multiple operations use a Guard.
Guard get() { return Guard(mutex, data); }
ConstGuard get() const { return ConstGuard(mutex, data); }
// For single operations you may provide convenience functions.
int get_value() const { return ConstGuard(mutex, data).data().get_value(); }
void set_value(int value) { Guard(mutex, data).data().set_value(value); }
private:
mutable Mutex mutex;
data* data;
};
std::shared_ptr<Object> make_object(const Object::Data& data) {
return std::make_shared<Object>(data);
}
(注:以上代码只是草图,我没有编译过(
说来话长。简短的是 [20.7.2.5] shared_ptr原子访问:
Concurrent access to a shared_ptr object from multiple threads does not
introduce a data race if the access is done exclusively via the functions
in this section and the instance is passed as their first argument.
- shared_ptr atomic_load(常量 shared_ptr* p(;
- void atomic_store(shared_ptr* p, shared_ptr r(;
- 。但我不熟悉这些功能。
不应该破坏物体的线程应该使用std::weak_ptr
来保持它,除了它主动使用它的时候。在此期间,weak_ptr
可以升级到std::shared_ptr
。
现在应该摧毁它的线可以坚持它的shared_ptr
,只要它认为合适,然后丢弃shared_ptr
。如果另一个线程只有一个weak_ptr
(未主动使用它(,则该对象将消失。如果另一个线程也有shared_ptr
,它会保留该对象,直到操作完成。
相关文章:
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- 如果两个线程相互依赖,则 cpp 线程连接应使用连接导致死锁
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 简单使用 std::atomic 在两个线程之间共享数据
- 如何使用 pthreads 以正确的方式设置两个线程之一的优先级
- 曼德布洛特 从一个线程被反复使用变为两个线程
- C++ 两个线程,共享几个整数变量
- 如何正确同步这两个线程?
- 两个线程尝试将一些数据读/写到数据库中表的同一行中
- 两个线程的公共资源 - 同步足够吗?
- 如果两个线程调用同一个函数,但函数中的所有变量都是局部变量,我还需要担心线程之间共享数据吗?
- 当两个线程同时尝试在同一静音上尝试try_lock()时会发生什么
- C 带有两个线程的boost async_read vs
- 使用 Poco:Condition 唤醒两个线程
- C 两个线程一个用于输入,一个用于输出
- 将两个线程同步到同一个计时器
- 全局变量的最终值,该变量正在通过两个线程进行增量
- C++中两个线程的互斥体
- Qthread char阵列在两个线程之间传递后被摧毁
- 如何使用CPP中使用一个对象运行同一类的两个线程