c++ - 多线程总和

标签 c++ multithreading

class Locker{
    mutex &m_mtx;
    public:
    Locker(mutex& mtx) : m_mtx{mtx}{m_mtx.lock();}
    ~Locker(){m_mtx.unlock();}
};
mutex mtx;
int globalOutput = 0;
void sum(const vector<int>& vect, int start, int end)
{
    for(auto i = vect.begin() + start; i != vect.begin() + end; ++i)
        {
            Locker{mtx};
            globalOutput+= *i;
        }
}

int main()
{
    const vector<int> vct(500, 2);

    thread th1(&sum, vct, 0, 250);
    thread th2(&sum, vct, 250, 500);

    th1.join();
    th2.join();

    std::cout << globalOutput;
}

我使用自定义 mutex 类来同步两个线程,这两个线程计算 500 个值为 2 的项目的总和。 您知道同步线程的另一种方法吗?分享知识,谢谢!

最佳答案

语句Locker{mtx};位于:

{
   Locker{mtx};
   globalOutput+= *i;
}

创建一个对象Locker,它锁定互斥体mtx,但该对象立即被销毁,互斥体被解锁。因此,globalOutput 由线程修改,同时不持有互斥锁。您可能需要:

{
   Locker locker{mtx};
   globalOutput+= *i;
   // locker object destroyed here
}

也就是说,您希望在修改 globalOutput 时保持对互斥锁的锁定。

<小时/>

使用std::lock_guardstd::scoped_lock

您可以使用 std::lock_guard而不是您的自定义 Locker 类:

{
   std::lock_guard<std::mutex> lck(mtx);
   globalOutput+= *i;
}

从 C++17 开始,您可以简单地使用 std::scoped_lock ,这使得 std::lock_guard 过时:

{
   // take advantage of C++17 template argument deduction for constructors
   std::scoped_lock lck(mtx);
   globalOutput+= *i;
}

关于c++ - 多线程总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60371865/

相关文章:

c++ - 使列表控件中的单个项目可编辑(C++、MFC)

c# - 如何在任务中传递多个参数

java - 连续线程执行

c++ - std::map 设计:使用 std::string 作为映射键和存储的对象名称(成员)

c++ - 无法访问特征线性系统解决方案的元素

c++ - 改进 C++ MFC 代码的工具

c - sqlite 内存数据库和多线程

java - 创建不同的 ImageView 对象 - 不同的时间

python - PyQt5 QDialog在后续线程中

c++ - 如何构造通过 std::allocator::allocate() 分配的对象?