我想知道锁、内存屏障和信号量之间的区别是什么?
(虽然其他问题可能提到锁和同步对象之间的区别,但我没有找到关于锁和内存屏障之间的区别的问题。)
内存屏障(也称为栅栏)是一种硬件操作,它确保对全局可见存储的不同读写的排序。在典型现代处理器上,内存访问是流水线化的,可能会无序发生。内存屏障确保这种情况不会发生。完整的内存屏障将确保在其之前发生的所有加载和存储在其之后发生的任何加载或存储之前发生。(许多处理器都支持部分屏障;例如,在Sparc上, membar#StoreStore
确保所有出现在它之前的存储将在出现在其之后的任何存储之前对所有其他进程可见。)
这就是内存屏障所做的全部。它不会阻止线程,也不会做其他任何事情。
互斥量和信号量是在操作系统中实现的更高级别的基元。请求互斥锁的线程将被阻塞,并且由操作系统挂起其执行,直到该互斥锁可用。操作系统中的内核代码将包含内存屏障指令以实现互斥锁,但它做了更多的工作;内存屏障指令将暂停硬件执行(所有线程),直到满足必要条件为止-最多一微秒的时间,并且整个处理器在此期间停止。当您尝试锁定互斥锁并且另一个线程已经拥有它时,操作系统将挂起您的线程(仅挂起您的线程-处理器继续执行其他线程),直到持有互斥锁的线程释放它,这可能需要几秒钟、几分钟甚至几天。(当然,如果超过几百毫秒,那么可能是一个错误)
最后,在信号量和互斥量之间实际上没有太大的区别;互斥量可以被认为是计数为一的信号量。
锁和信号量之间的一个重要区别在于线程拥有锁,因此不应尝试解锁其他线程,而对于信号量则不是这种情况。
现在先简单解释一下。
锁定
是一个原子测试,用于判断这段代码是否可以继续执行。
lock (myObject)
{
// Stuff to do when I acquire the lock
}
Thread.MemoryBarrier();
public static Singleton Instance()
{
if (_singletonInstance == null)
{
lock(myObject)
{
if (_singletonInstance == null)
{
_singletonInstance = new Singleton();
}
}
}
}
这是一组CPU指令,用于实现内存屏障,明确告诉CPU不能乱序执行操作。
信号量
与锁类似,但通常用于多个线程。例如,如果您可以处理10个并发磁盘读取操作,则会使用信号量。根据处理器的不同,这可能是自己的指令,或者是测试和设置指令,需要在中断周围进行更多的工作(例如,在ARM上)。
m_NumRunningThreads==0
不会触发多次。我的理解正确吗? - xcrypt