这篇文章:http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf(第12页) 似乎在锁和内存障碍之间有所区别
我想知道锁,内存屏障和信号量之间的区别是什么?
(虽然其他问题可能会提到锁和同步对象之间的区别,但我没有发现锁和内存屏障之间的区别)
答案 0 :(得分:8)
锁和信号量之间的一个很大区别是线程拥有锁,因此没有其他线程应该尝试解锁,而信号量不是这种情况。
答案 1 :(得分:8)
内存屏障(也称为围栏)是一种硬件操作
确保对全局的不同读写顺序
可见商店。在典型的现代处理器上,存储器访问是
流水线,可能发生故障。内存屏障确保了这一点
这不会发生。完整的内存屏障将确保所有负载
它之前的商店和商店在随后的任何商店或商店之前发生
它。 (许多处理器支持部分障碍;例如在Sparc上,a
membar #StoreStore
确保在它之前发生的所有商店
在之后发生的任何商店之前对所有其他进程可见
它)。
这就是记忆障碍。它不会阻塞线程,或 任何东西。
互斥体和信号量是更高级别的灵长类动物,在实现中 操作系统。请求互斥锁的线程将阻塞,和 执行程序暂停执行,直到该互斥锁是空闲的。该 OS中的内核代码将按顺序包含内存屏障指令 实现互斥,但它做得更多;记忆障碍 指令将暂停硬件执行(所有线程),直到 必要条件已达到 - 一微秒左右 大多数,整个处理器停止这段时间。当你尝试 锁定互斥锁,另一个线程已经拥有它,操作系统将暂停 你的线程(只有你的线程 - 处理器继续 执行其他线程)直到持有互斥锁的人释放它,哪个 可能是几秒,几分钟甚至几天。 (当然,如果它不仅仅是一个 几百毫秒,这可能是一个错误。)
最后,信号量和信号量之间并没有太大区别 互斥;互斥量可以被认为是一个计数为1的信号量。
答案 2 :(得分:2)
现在的简单说明。
<强>锁定强>
对这段代码是否可以继续进行原子测试
lock (myObject)
{
// Stuff to do when I acquire the lock
}
这通常是单个CPU指令,用于测试变量并将其设置为单个原子操作。更多信息,http://en.wikipedia.org/wiki/Test-and-set#Hardware_implementation_of_test-and-set_2
记忆障碍
是否向处理器提示它无法按顺序执行这些指令。没有它,指令可以不按顺序执行,就像在双重检查锁定中一样,可以在锁定之前执行两次空检查。
Thread.MemoryBarrier();
public static Singleton Instance()
{
if (_singletonInstance == null)
{
lock(myObject)
{
if (_singletonInstance == null)
{
_singletonInstance = new Singleton();
}
}
}
}
这也是一组CPU指令,它们实现了内存屏障,以明确告诉CPU它不能无序地执行操作。
<强>信号灯强>
类似于锁,除了它们通常用于多个线程。即例如,如果您可以处理10个并发磁盘读取,则使用信号量。根据处理器的不同,这可以是它自己的指令,也可以是带有更多中断的测试和设置指令(例如在ARM上)。