C 返回功能lock_guard

C++ return function lock_guard

本文关键字:guard lock 功能 返回      更新时间:2023-10-16

我有包裹在shared_ptr中的资源"资源",我想从其他线程访问它。当我这样做时:

// foo.h
class Foo{
public:
    std::shared_ptr<Setup> GetSomeThing();
    void SetSomeThing();
private:
    std::shared_ptr<Setup> resource;
    std::mutex lock;
}
//Foo.cpp
std::shared_ptr<Setup> Foo::GetSomeThing()
{
    std::lock_guard<std::mutex> lock (mutex);
    return resource;
}
void Foo::SetSomeThing()
{
     std::lock_guard<std::mutex> lock (mutex);
     resource = ...;
}

一切都可以吗?什么时候将创建一个返回对象,什么时候将被销毁?文档中有什么事吗?谢谢!

此答案假定这两行:

std::lock_guard<std::mutex> lock (mutex);

都被

替换
std::lock_guard<std::mutex> guard (lock);

如果多个线程访问无同步的std::shared_ptr<>的单个实例,并且任何呼叫的非const成员中的任何一个都会发生数据竞赛。

这意味着您必须确保SetSomeThing()GetSomething()之间的同步。

引入std::mutex并以建议的方式使用std::lock_guard<>。返回的副本将是在称为guard的击曲率之前构建的。

请注意,这是大约同一实例。GetSomeThing()返回的副本具有足够的内部同步,以确保可以在不同步其他实例的情况下访问(非const甚至破坏)。

但是,这都没有阻止在std::shared_ptr<Setup>拥有的任何共享Setup对象(部分)上进行数据竞赛。如果仅读取对Setup的所有访问权限,则可以访问多个线程,但是如果任何线程都会写入数据竞赛的共享数据(问题中未显示进一步的同步)。

在简单应用程序中,像Setup这样的对象可以在启动并破坏多个线程终止后启动和破坏多个线程之前构造和初始化。在这种特定情况下,不需要进一步的同步,即使提供的锁也是多余的。

这是一个非规范的参考:

http://en.cppreference.com/w/cpp/memory/shared_ptr

请参阅开头描述的最后一段。

脚注:更改应用程序"设置"可能要比简单地确保不会在属性上发生数据竞赛要困难得多。线程可能需要剪裁采用更改或"放弃"活动。例如,考虑一个图形程序,其中在"绘制"步骤中更改屏幕分辨率。它应该完成抽奖并产生太大/小或倾倒零件画布并采用新分辨率的画布吗?是否以某种方式获得了设置,以使抽奖产生与"之前"或"之后"的东西,而不是某些毫无意义(可能崩溃的)混合动力?