多个矢量编写器没有锁定

时间:2018-01-03 13:33:51

标签: c++ multithreading vector thread-safety

我有几个线程在向量中写入。不同的线程尝试写同一个字节是可能的。没有读物。我可以只使用atomic_fecth_or(),就像在示例中一样,因此向量将变为线程安全吗?它与GCC编译时没有错误或警告。

    std::vector<std::atomic<uint8_t>> MapVis(1024*1024); 

    void threador()
    {
    ...
    std::atomic_fetch_or(&MapVis[i], testor1); 
    }

2 个答案:

答案 0 :(得分:3)

  

它与GCC编译时没有错误或警告

这并不意味着什么,因为编译器不会执行那种并发分析。有专门的静态分析工具,可以通过不同程度的成功来实现这一目标。

  

我是否只能使用atomic_fetch_or ...

你当然可以,并且在每个人std::atomic<uint8_t>的水平上都是安全的。

  

...向量将变为线程安全吗?

安全访问每个元素是不够的。您特别需要避免任何使迭代器无效的操作(swap,resize,insert,push_back等)。

我不愿意在这种情况下说vector是线程安全的 - 但是你将自己限制在其接口的线程安全子集中​​,这样它才能正常工作。

请注意,正如VTT建议的那样,如果可能的话,为每个线程保留单独的部分向量会更好。部分是因为它更容易证明是正确的,部分是因为它避免了核心之间的错误共享。

答案 1 :(得分:2)

是的,由于atomic opperations得到保证,因此保证是线程安全的

  

与中断,信号,并发进程和线程隔离

因此,当您以原子方式访问MapVis元素时,您可以保证写入其中的任何其他进程已经完成。并且在完成写作之前,您的过程不会被中断。

如果你使用的是非原子变量,那就是:

  1. 线程A获取MapVis[i]
  2. 的值
  3. 主题B获取MapVis[i]
  4. 的值
  5. 线程A将ored值写入MapVis[i]
  6. 线程B将ored值写入MapVis[i]
  7. 正如你所看到的,线程B需要等到线程A完成写入,否则它只会将线程A的更改踩到MapVis[i]。使用原子变量,并发线程不会中断提取和写入。这意味着线程B无法中断线程A的读写操作。