【发布时间】:2021-11-18 20:03:29
【问题描述】:
我正在阅读 C++ 并发操作。 它说当你使用 std::execution::par 时,你可以使用每个内部元素的互斥锁,如下所示。
#include <mutex>
#include <vector>
class X {
mutable std::mutex m;
int data;
public:
X() : data(0) {}
int get_value() const {
std::lock_guard guard(m);
return data;
}
void increment() {
std::lock_guard guard(m);
++data;
}
};
void increment_all(std::vector<X>& v) {
std::for_each(v.begin(), v.end(), [](X& x) { x.increment(); });
}
但是它说当你使用 std::execution::par_unseq 时,你必须用下面这样的整个容器互斥体替换这个互斥体
#include <mutex>
#include <vector>
class Y {
int data;
public:
Y() : data(0) {}
int get_value() const { return data; }
void increment() { ++data; }
};
class ProtectedY {
std::mutex m;
std::vector<Y> v;
public:
void lock() { m.lock(); }
void unlock() { m.unlock(); }
std::vector<Y>& get_vec() { return v; }
};
void incremental_all(ProtectedY& data) {
std::lock_guard<ProtectedY> guard(data);
auto& v = data.get_vec();
std::for_each(std::execution::par_unseq, v.begin(), v.end(),
[](Y& y) { y.increment(); });
}
但是即使你使用第二个版本,并行算法线程中的 y.increament() 也存在数据竞争条件,因为并行算法线程之间没有锁。
带有 std::execution::par_unseq 的第二个版本如何是线程安全的?
【问题讨论】:
标签: c++ concurrency c++17 mutex parallel.foreach