我有几个线程在向量中写入。不同的线程尝试写同一个字节是可能的。没有读物。我可以只使用atomic_fecth_or()
,就像在示例中一样,因此向量将变为线程安全吗?它与GCC编译时没有错误或警告。
std::vector<std::atomic<uint8_t>> MapVis(1024*1024);
void threador()
{
...
std::atomic_fetch_or(&MapVis[i], testor1);
}
答案 0 :(得分:3)
它与GCC编译时没有错误或警告
这并不意味着什么,因为编译器不会执行那种并发分析。有专门的静态分析工具,可以通过不同程度的成功来实现这一目标。
我是否只能使用
atomic_fetch_or
...
你当然可以,并且在每个人std::atomic<uint8_t>
的水平上都是安全的。
...向量将变为线程安全吗?
安全访问每个元素是不够的。您特别需要避免任何使迭代器无效的操作(swap,resize,insert,push_back等)。
我不愿意在这种情况下说vector是线程安全的 - 但是你将自己限制在其接口的线程安全子集中,这样它才能正常工作。
请注意,正如VTT建议的那样,如果可能的话,为每个线程保留单独的部分向量会更好。部分是因为它更容易证明是正确的,部分是因为它避免了核心之间的错误共享。
答案 1 :(得分:2)
是的,由于atomic opperations得到保证,因此保证是线程安全的:
与中断,信号,并发进程和线程隔离
因此,当您以原子方式访问MapVis
元素时,您可以保证写入其中的任何其他进程已经完成。并且在完成写作之前,您的过程不会被中断。
如果你使用的是非原子变量,那就是:
MapVis[i]
MapVis[i]
MapVis[i]
MapVis[i]
正如你所看到的,线程B需要等到线程A完成写入,否则它只会将线程A的更改踩到MapVis[i]
。使用原子变量,并发线程不会中断提取和写入。这意味着线程B无法中断线程A的读写操作。