锁,记忆障碍,信号量之间的区别

xcr*_*ypt 4 c++ multithreading

这篇文章:http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf(第12页)似乎在锁和内存屏障之间有所不同

我想知道锁,内存屏障和信号量之间的区别是什么?

(虽然其他问题可能会提到锁和同步对象之间的区别,但我没有发现锁和内存屏障之间的区别)

ste*_*anv 9

  • 存储器屏障是订购的存储器访问的方法.编译器和CPU可以更改此顺序以进行优化,但在多线程环境中,这可能是一个问题.与其他人的主要区别在于线程不会被此停止.
  • 一个锁或互斥可确保代码只能被1个线程访问.在本节中,您可以将环境视为单线程,因此不需要内存屏障.
  • 一个信号量基本上是可以增加(V())或减小计数器(P()).如果计数器为0,则p()暂停线程,直到计数器不再为0.这是一种同步线程的方法,但我更喜欢使用互斥锁或条件变量(有争议,但这是我的看法).当初始计数器为1时,信号量称为二进制信号量,它类似于锁.

锁和信号量之间的一个很大区别是线程拥有锁,因此没有其他线程应该尝试解锁,而信号量不是这种情况.


Jam*_*nze 8

内存屏障(也称为围栅)是一种硬件操作,可确保对全局可见存储的不同读写顺序.在典型的现代处理器上,存储器访问是流水线的,并且可能不按顺序发生.内存屏障可确保不会发生这种情况.完整的内存屏障将确保其前面的所有加载和存储在其后的任何加载或存储之前发生.(许多处理器都支持部分障碍;例如,在Sparc上,a membar #StoreStore确保在它之前发生的所有商店在其之后发生的任何商店之前对所有其他进程可见.)

这就是记忆障碍.它不会阻塞线程或任何东西.

互斥体和信号量是更高级别的灵长类动物,在操作系统中实现.请求互斥锁的线程将阻塞,并由OS暂停执行,直到该互斥锁空闲.操作系统中的内核代码将包含内存屏障指令以实现互斥锁,但它可以做更多事情; 内存屏障指令将暂停硬件执行(所有线程),直到满足必要条件 - 最多一微秒左右,整个处理器停止此时间.当您尝试锁定互斥锁,而另一个线程已经拥有它时,操作系统将暂停您的线程(并且只有您的线程 - 处理器继续执行其他线程),直到持有互斥锁的任何人释放它,这可能是秒,分钟或双数日.(当然,如果它超过几百毫秒,它可能是一个错误.)

最后,信号量和互斥量之间没有太大区别; 互斥锁可以被视为计数为1的信号量.