gpt4 book ai didi

c++ - 如何安全地销毁一个经常被两个不同线程访问的对象?

转载 作者:太空宇宙 更新时间:2023-11-04 11:49:06 25 4
gpt4 key购买 nike

我目前遇到的问题是必须释放一个经常被两个不同线程访问的对象(实例)。对我来说,两个线程中的哪一个正在破坏实例并不重要,但我更喜欢那个也创建它的线程,尽管我认为这根本不重要。

所以在应该销毁对象的线程检测到应该删除对象的场景中,在调用析构函数时,另一个线程正在访问该对象的成员(函数),可能是某种运行时会发生错误。

我对这个主题做了一些研究,但我只能理解人们在说:“为什么要删除一个仍然需要存在的对象”。但在我的例子中,在一个线程正在执行的一段代码决定销毁它之后,它应该不再被需要。

我会很感激一个答案,比如一本涵盖这个主题的好书或文章的提示,但请随意写下你将如何解决这个问题。

最佳答案

您需要双重间接访问来管理对数据的并发访问:

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(const shared_ptr* p);
  • void atomic_store(shared_ptr* p, shared_ptr r);
  • ...但是我不熟悉这些功能。

关于c++ - 如何安全地销毁一个经常被两个不同线程访问的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19033194/

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