原子操作和线程安全之间的区别?


10

从讨论中,我看到原子操作线程安全似乎是同一回事,但是很多人说它们是不同的。有人能告诉我区别吗?


4
原子操作将有助于确保线程安全,但是它们怎么可能是同一回事呢?“线程”与“操作”不同。
user50849

Answers:


11

原子操作是通过使用诸如互斥锁或信号量之类的某种锁来实现线程安全的方法,这些锁在内部使用原子操作,或者通过使用原子和内存栅栏实现无同步。

因此,对原始数据类型的原子操作是实现线程安全的工具,但不能自动确保线程安全,因为您通常有多个相互依赖的操作。您必须确保完成这些操作而不会中断,例如使用Mutexes。

是的,用c#编写这些原子数据类型之一是线程安全的,但这并不能使您在线程中使用它们的函数安全。即使第二个线程“同时”访问它,它也只能确保正确执行一次写操作。不管怎样,不能确保从当前线程的下一次读取获得先前写入的值,因为可能已经向另一个线程写入了该值,只是读取的值是有效的。


int,bool,float是线程安全的还是原子的?
user960567

1
@ user960567-数据类型就是:数据类型。由编译器决定如何访问它们。考虑一下8086 CPU上的int64。
mouviciel 2012年

2
特别是在C#中,对问题进行标记,读写必须在基本数据类型上是原子的。请参阅Ecma 334
user50849

2
是的,用c#编写这些原子数据类型之一是线程安全的,但这并不能使您在线程中使用它们的函数安全。即使第二个线程“同时”访问它,它也只能确保正确执行一次写操作。不管怎样,不能确保从当前线程的下一次读取获得先前写入的值,因为可能已经向另一个线程写入了该值,只是读取的值是有效的。
Archy 2012年

4
x = 5在c#中是原子的。但是在执行此操作后,它可能会立即被覆盖。x = x + 1通过以下步骤执行:1.将x加载到寄存器2.将x递增到寄存器3.将x存储到内存中。如果第二个线程同时执行相同的操作,则两个线程都将加载相同的值,将其递增并存储,导致x仅递增一次而不是两次。InterlockedIncrement要么使用特殊的处理器指令来执行原子增量,要么通过使用诸如CAS的锁定机制来确保这一点,以确保在不写入新值的同时,其他任何线程都不能读取旧值。
Archy 2012年

3

原子性和线程安全性是两个不同的事物。原子性是指操作的“全有或全无”质量。如果不能100%成功地执行某项操作,则系统应保持在该操作任何部分开始之前的总体状态。典型的例子是数据库事务。保存发票(包括抬头和多个行项目)时,必须成功放置每个数据库行中的每个部分;如果不是,则数据丢失或损坏。如果无法插入订单项,则不仅不应插入剩余的其他行,而且不应保留已处理的任何行。

线程安全性是指事物的组合,包括原子性,它使操作可以“重入”。多个工作人员可以在相同或不同的时间开始执行相同的操作,而不会影响任何其他操作。有许多用于线程安全操作的模型。它们中的大多数在概念上可以归结为完全隔离地运行多个并行任务(两个工作人员可以在两个不同的对象或对象集合上执行同一任务,甚至不知道另一个工作人员是否存在),或者在其中建立“管道”多个工人在整个操作中都执行一个任务(每个工人从第一个任务前进到下一个任务,依此类推,或者专注于一个任务并将其中间的“工作产品”交给下一个工人)。


2

原子操作是不能中断的操作。

安全线程是可以安全中断的线程。

线程安全性是通过原子操作获得的,尤其是在防止多次访问关键资源的逻辑中。

基本的原子操作是Test-and-set,用于实现信号量,而信号量又用于实现线程安全。


如果可以保证回滚更改,是否不能中断多步操作并将其称为原子操作?
user50849

1
否。原子应从词源上理解:ἄτομος,atomos,不可分割。
mouviciel 2012年

int,bool,float是线程安全的还是原子的?
user960567

但是,是不是有这之间的差异 indivisble,并出现不可分割的观察者?根据您的定义,原子操作不能包含多个步骤。我相信维基百科对原子操作的定义中的“出现”一词很重要。(如果有人要把它带到那里,我正在聊天中):)
user50849

有一个很大的不同:安全线程可以被中断,并且没有保证多少时间。这对于实时计算至关重要。原子操作(如果是多步操作,则具有中断锁定)被保证在可预测的时间后终止。
mouviciel 2012年

1

线程安全更像是一个框架或“概念”,原子操作是一个子集,是一种获得状态的方法(一种),被分类为“线程安全”。

线程安全是指可以由单独的线程访问的进程,其中一个线程的访问(和数据操作)不会破坏另一个线程的操作的完整性。

程序员的很多技能都知道如何实现此目标,具体取决于情况和关键目标,例如,您可能需要实现:锁,信号量,闩锁,原子对象,同步规则等。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.