C ++线程写入向量数组的不同部分

时间:2014-07-15 12:45:57

标签: multithreading c++11 thread-safety

我有一个std::array<std::vector, NUM_THREADS>,我基本上希望每个线程获取一些数据,并将其存储在自己的std::vector中,并从其向量中读取。

这样安全吗?或者我将不得不使用互斥量或什么?

1 个答案:

答案 0 :(得分:2)

关于数据竞争的规则是,如果每个内存位置一次只能被一个线程访问,或者只被读取(通过任意数量的线程,但没有写入),那么你就不会需要原子性。否则,您需要原子性或同步(例如互斥)。

如果每个线程只是写入和读取自己的向量,这将是安全的。如果两个线程在没有同步的情况下写入相同的向量元素,或者如果它们都写入相同的向量本身(例如,附加或截断向量),那么你很漂亮多遭受重创 - 这是两次同时写的。如果两个线程都写入自己的向量元素并从两个向量中读取,那么它会更复杂,但总的来说我会期望它不安全。有一些非常具体的安排可能是安全/合法的,但它们会非常脆弱,而且可能难以维护,因此重新设计以避免它可能会更好。

作为一个这样的用法的例子,它是合法的(但同样,在代码维护期间脆弱且难以保持安全性)将是没有向量改变大小的地方(重新分配将是写入向量本身将阻止对其他线程对向量或其元素的任何读取)并且每个线程都能够避免从写入的向量的任何特定元素中读取通过任何其他线程(例如,你有两个线程,一个读取和写入向量的偶数元素,另一个读取和写入向量的奇数元素)。

以上示例非常人为,可能并非对可能需要的实际访问模式有用。我能想到的其他例子可能也是人为的,无益的。并且很容易做一些会破坏整个保证的简单操作。特别是,如果任何线程在它们自己的向量上执行push_back(),那么可能同时读取向量的任何线程几乎都会保证导致未定义的行为。 (您可以非常仔细地使用reserve()对齐星星并制作合法的代码,但我当然不会自己尝试。)