两个线程都从相同的变量中读取,这会导致任何问题吗?据我了解,只有写作会导致并发问题......
这应该没问题。显然,只要在两个线程开始读取之前初始化数据并在两个线程完成后销毁。
调用相同的函数会导致任何并发问题吗?再说一次,据我所知,这应该不是问题......
是和不是。没有代码很难说。函数有什么作用?它是否依赖于共享状态(例如static
变量、全局变量、单例...)?如果是,那么这绝对是一个问题。如果从来没有任何共享状态,那么你就可以了。
两个线程唯一一次写入同一个变量是在保存计算的像素颜色时。这存储在一个数组中,但它们从不写入该数组中的相同索引。这会导致问题吗?
也许有时候。什么数组?if 可能是安全的sizeof(element) == sizeof(void*)
,但是 C++ 标准在多线程上是静音的,因此它不会强制您的编译器强制您的硬件使其安全。您的平台可能会在这里咬您(例如,64 位机器和一个写入 32 位的线程可能会覆盖相邻的 32 位值),但这并不是一种不常见的模式。通常你最好使用同步来确定。
您可以通过以下几种方式解决此问题:
我的回答中缺乏承诺是使多线程编程变得困难的原因:P
例如,来自Intel® 64 and IA-32 Architectures Software Developer's Manuals描述了不同平台如何保证不同级别的原子性:
7.1.1 保证原子操作
Intel486 处理器(以及之后的更新处理器)保证以下基本内存操作将始终以原子方式执行:
- 读取或写入一个字节
- 读取或写入在 16 位边界上对齐的字
- 读取或写入在 32 位边界上对齐的双字
Pentium 处理器(以及之后的更新处理器)保证以下额外的内存操作将始终以原子方式执行:
- 读取或写入在 64 位边界上对齐的四字
- 对适合 32 位数据总线的未缓存内存位置进行 16 位访问
P6 系列处理器(以及之后的更新处理器)保证以下附加内存操作将始终以原子方式执行:
- 对适合高速缓存行的高速缓存内存进行未对齐的 16、32 和 64 位访问
Intel Core 2 Duo、Intel Atom、Intel Core Duo、Pentium M、Pentium 4、Intel Xeon、P6 系列、Pentium 不保证对跨总线宽度、缓存行和页面边界拆分的可缓存内存的访问是原子的, 和 Intel486 处理器。Intel Core 2 Duo、Intel Atom、Intel Core Duo、Pentium M、Pentium 4、Intel Xeon 和 P6 系列处理器提供总线控制信号,允许外部存储器子系统使分离访问原子化;但是,不对齐的数据访问会严重影响处理器的性能,应该避免。