如果其他线程不会访问它,在没有锁的线程中更新对象是否安全?

Is it safe to update an object in a thread without locks if other threads will not access it?

我有一个实体向量。在更新周期,我遍历向量并更新每个实体:读取它的位置,计算当前速度,写入更新的位置。此外,在更新过程中,我可以在程序的其他部分更改一些其他对象,但每个对象仅与当前实体相关,其他实体不会触及该对象。

所以,我想 运行 线程中的这段代码。我将 vector 分成几个块,并在不同的线程中更新每个块。如我所见,线程是完全独立的。每次迭代中的每个线程都使用独立的内存区域,不会影响其他线程的工作。

这里需要锁吗?我假设,一切都应该在没有任何互斥锁等的情况下工作。我说得对吗?

简答

不,您不需要任何锁定或同步机制,因为您的问题似乎是 embarrassingly parallel task

更长的答案

仅当两个线程可能同时访问同一内存时才会出现的竞争条件并且至少其中一个访问是写操作。如果你的程序暴露了这个特征,那么你需要确保线程以有序的方式访问内存。一种方法是使用锁(但它不是唯一的方法)。否则结果为 UB。 您似乎找到了一种在线程之间拆分工作的方法 s.t。每个线程都可以独立于其他线程工作。这是并发编程的最佳情况,因为它不需要任何同步。代码的复杂度大大降低,通常加速比会跳起来。

请注意,正如 @acelent 在评论部分指出的那样,如果您需要一个线程所做的更改在另一个线程中可见,那么您可能需要某种同步,因为取决于在一个线程中对内存模型和硬件所做的更改可能不会立即在另一个线程中可见。

这意味着您可能从 Thread 1 写入一个变量,一段时间后从 Thread 2 读取相同的内存,但仍然无法看到 Thread 1 所做的写入.

"I separate vector into few chunks and update each chunk in different threads" - 在这种情况下,您不需要任何锁或同步机制,但是,系统性能可能会由于错误共享而显着降低,具体取决于块如何分配给线程。请注意,编译器可能会使用线程私有时间变量来消除错误共享。

您可以在书籍和 wiki 中找到大量信息。这是一些信息 https://software.intel.com/en-us/articles/avoiding-and-identifying-false-sharing-among-threads 还有一个Whosebug post这里