c++ - 共享互斥量是否比相对较大结构的原子更有效?

标签 c++ multithreading c++11 mutex atomic

假设我有一个看起来像这样的类(实际上正是这个大小):

class K
{
public:

    long long get_x() const; // lock m_mutex in shared/read-only mode

    void update( long long w ); // lock m_mutex with a unique_lock

private:
    long long m_a;
    long long m_b;
    long long m_c;
    long long m_x;
    double m_flow_factor;

    mutable boost::shared_mutex m_mutex;
};

如您所见,这应该是线程安全的。更新函数一次被一个线程调用,未知但只有一个线程(保证),但访问器可以同时被多个线程调用。

update 函数正在更改所有值并且被调用得非常频繁(每秒一百次)。正如您猜到的那样,当前的实现会锁定很多。

我正在考虑使用 std::atomic 来避免锁定并可能使此代码更高效。但是,我确实需要更新函数来一起更新值。 因此,我正在考虑做这样的事情:

class K
{
public:

    long long get_x() const
    { return data.load().x; }

    void update( long long w )
    {
        auto data_now = data.load();
        // ... work with data_now
        data.store( data_now );
    }

private:
    struct Data {
    long long a;
    long long b;
    long long c;
    long long x;
    double flow_factor;
    };
    std::atomic<Data> data;
};

我目前对 std::atomic 的理解是,即使这段代码比之前的代码更具可读性(因为它没有到处都有锁声明),因为 K::Data 结构是“大", std::atomic 将只用普通的互斥锁实现(所以无论如何它都不应该比我最初的实现更快)。

我说的对吗?

最佳答案

任何对 std:atomic 的特殊化都将涉及内部锁定,因此您一无所获,现在您还面临着以前没有的加载和存储之间的数据竞争,就像这样在以前的版本中对整个 block 进行了独占锁定(我想?)。

此外,对于 shared_mutex,使用普通互斥锁与 shared_mutex 进行分析可能是明智的,您可能会发现普通互斥锁的性能更好(这一切都取决于您持有锁的时间)。

shared_mutex 的好处只有在长时间持有锁以进行读取并且写入很少时才能看到,否则 shared_mutex 中涉及的开销会扼杀您对普通互斥锁的任何 yield 。

关于c++ - 共享互斥量是否比相对较大结构的原子更有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14008799/

相关文章:

C++:将 std::function 转换为 gsl_function

c++ - 赋值运算符中的内存泄漏

c++ - OpenGL RGB DXT1压缩纹理mipmap上传

c++ - 如何使用 win32 从多线程上下文初始化线程原语?

java - 安全地使用/交换 Collections.synchronizedList

c++ - 类型检测 : using variadic arguments to properly implement a function that calculates the mean

c++ - 在另一个线程上调用非静态类函数

c++ - 创建一个 C++ 模板函数,它将返回特定大小的 std::array

.net - 托管线程多久切换一次操作系统线程?

c++ - 如何修复无限 while 循环?