互斥锁,信号量和读写锁之间有什么区别

时间:2013-08-03 20:52:35

标签: mutex semaphore readerwriterlock

任何实时场景解释都会受到赞赏。 除了pthreads之外还有其他方法来处理同步。 互斥体与递归互斥体(任何实时场景)有何不同?

2 个答案:

答案 0 :(得分:5)

互斥锁可用于保护共享资源(变量,文件,外围设备)免受可能使其处于不一致状态的修改。

信号量可用于管理相同共享资源的有限池(其中一个重要的例子是 IPC队列)。线程可以从池中获取资源,将一个资源放入池中,或者等待一个资源可用。请注意,除了信号量之外,您可能仍需要使用互斥锁(以保护池数据结构本身)。

读写锁可用于保护可以读取或写入(修改)的共享资源。所有读者线程都可以同时访问它。作者线程需要独占访问权。

可以使用条件变量和互斥锁来发出事件信号。

Wikipedia可用于阅读大部分内容。

答案 1 :(得分:2)

boost::interprocess文档

中非常清楚地回答了这一问题
  

什么是互斥体?

     

Mutex代表互斥,它是最基本的形式   进程之间的同步。互斥锁保证只有一个   线程可以锁定给定的互斥锁。如果代码部分被a包围   互斥锁定和解锁,它保证只有一个线程   时间执行该部分代码。当该线程解锁时   互斥,其他线程可以进入该代码区域:

     

//先前构建了互斥锁

     

lock_the_mutex();

     

//这段代码一次只能由一个线程执行。

     

unlock_the_mutex();互斥锁也可以是递归的或非递归的:

     

递归互斥锁可以被同一个线程锁定多次。至   完全解锁互斥锁,线程必须解锁互斥锁   它锁定了它的时间。非递归互斥锁无法锁定多个   时间由同一个线程。如果一个线程锁定了一个互斥锁,那么   结果是未定义的,它可能会抛出错误或线程可能   永远被阻止。   提升进程间文档

  

什么是信号量?

     

信号量是基于的进程之间的同步机制   内部计数,提供两种基本操作:

     

等待:测试信号量计数的值,然后等待值   小于等于0.否则,减少信号量   计数。发布:增加信号量计数。如果有任何过程   被阻止,其中一个进程被唤醒。如果是最初的信号量   count初始化为1,Wait操作相当于互斥锁   锁定和Post相当于互斥锁解锁。这类   信号量被称为二进制信号量。

     

虽然信号量可以像互斥量一样使用,但它们具有独特性   功能:与互斥锁不同,Post操作不需要执行   执行Wait操作的相同线程/进程。   boost::interprocess docs

boost interprocess并没有明确地拥有一个叫做读写器锁的东西,但它确实使用shared_locksupgrade_lockupgrade_to_unique lock

来实现它们
  

什么是可共享和可升级的互斥锁?

     

可共享和可升级的互斥锁是提供更多功能的特殊互斥锁类型   锁定可能性比普通互斥锁。有时,我们可以   区分读取数据和修改数据。如果只是   一些线程需要修改数据,并使用普通的互斥锁   保护数据不受并发访问的影响,并发性非常好   有限:只读取数据的两个线程将被序列化   而不是同时执行。

     

如果我们允许并行访问只读取数据的线程但是   我们避免读取和修改的线程之间的并发访问   在修改的线程之间,我们可以提高性能。这是   特别适用于数据读取比较常见的应用程序   数据修改和同步数据读取代码需要一些   时间执行。使用可共享的互斥锁,我们可以获得2种锁定类型:

     

独占锁:类似于普通的互斥锁。如果一个线程获得了   独占锁定,没有其他线程可以获得任何锁定(独占或   其他)直到独占锁被释放。如果其他任何线程有   任何除独占之外的锁,一个试图获得独家的线程   锁将阻止。这个锁将由线程获取   修改数据。可共享锁:如果线程获得可共享锁,   其他线程无法获得独占锁。如果有任何线程   获得了一个试图获得可共享锁的线程的独占锁   会阻止。此锁定由只需要读取的线程执行   数据。使用可升级的互斥锁,我们可以获得以前的锁定加   一个新的可升级锁:

     

可升级锁定:获取可升级锁定与获取类似   特权共享锁。如果一个线程获得了一个可升级的锁,   其他线程可以获得可共享的锁。如果有任何线程已获得   一个线程尝试获取的独占或可升级锁定   可升级锁将阻止。获得可升级的线程   锁,保证能够原子地获得一个独占锁   当获得可共享锁的其他线程释放它时。这个   用于可能需要修改数据的线程,但通常   只需要读取数据。该线程获取可升级锁   和其他线程可以获得共享锁。如果可升级   线程读取数据,它必须修改它,线程可以   提升获得独占锁:当所有可共享的线程都有   发布了可共享锁,可升级锁被原子升级   独家锁定。新提升的线程可以修改数据   并且可以肯定没有其他线程在执行时修改它   过渡。只有1个线程可以获得可升级(特权   读者)锁定。   boost interprocess docs

C ++本身还没有reader-writer locks(使用共享的互斥锁)但@Howard Hinnet确实尝试将它们放在那里,如果你看here他也提供了代码

C ++没有信号量,就我所知,互斥量只在新的C ++ 11标准中,这导致了为什么大部分都是关于boost::interprocess