多线程上下文中弱指针未过期则更新

问题描述 投票:0回答:1

client 持有一个指向 double

 值的共享指针,
server 通过持有 weak_pointer
 在另一个分离线程上更新此值,服务器检查 
weak_pointer
 是否已过期以及是否已过期。不,它会从安全向量中删除。我怀疑这不起作用,因为 
shared_ptr
 可能会从客户端
之间被破坏,我对 expired()
 的阅读(我认为这是线程安全的,因为我想象它指的是 
shared_ptr
 的原子计数器)
并且 我的价值更新。有没有办法让检查 expired()
lambda
 函数在销毁之前更新值?我的意思是:

struct server { public: static void subscribe(const std::shared_ptr<double>& d) { m_values.safe_push_back(d); //safely pushes back in the vector } void update() { auto updater = [](std::weak_ptr<double>& wd) { if(wd.expired()) wd = nullptr; else *wd += 2.0; //This is not thread safe I guess? }; m_values.safe_remove_all(nullptr); m_values.safe_visit(updater); }; private: static safe_vector<std::weak_ptr<double>> m_values; }
struct client
{
    void subcribe_sleep_print(const double random_seconds)
    {
        std::shared_ptr<double> d = std::make_shared<double>(0.0); //for the sake of the example assume we create subscribe before sleep
        server::subscribe(d);
        sleep_for_seconds(random_seconds); //sleeps for some random time in seconds.
        std::cout << *d << std::endl;
    }
}
想象 

server::update

client::subcribe_sleep_print
 在不同的线程上运行。这不安全,因为服务器写入时 
shared_ptr
 可能会被破坏?有没有办法在没有用户(我)定义的原子或互斥体的情况下实现这一点?我不介意它是否在后台使用,只要我自己不添加它们(原子/互斥),因为我知道共享指针已经使用原子计数器。

c++ multithreading thread-safety shared-ptr weak-ptr
1个回答
1
投票
else *wd += 2.0; //This is not thread safe I guess?

不,它不是线程安全的。您面临着竞争条件,在您检查过期之后,指针可能会过期。在这种情况下,您现在已取消引用

nullptr

因此,正确的方法是显式使用

std::weak_ptr<T>::lock()

 来尝试获取关联的共享指针(这也是 
expired()
 内部所做的),并且只有当获得有效的指针时,您才可以执行读取或写入操作访问。

如果您没有获得有效的共享指针,请将其视为

expired()

 返回了 false。

© www.soinside.com 2019 - 2024. All rights reserved.