作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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_guard
或std::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/
我是一名优秀的程序员,十分优秀!