任何实时场景解释都会受到赞赏。 除了pthreads之外还有其他方法来处理同步。 互斥体与递归互斥体(任何实时场景)有何不同?
答案 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_locks
,upgrade_lock
和upgrade_to_unique lock
什么是可共享和可升级的互斥锁?
可共享和可升级的互斥锁是提供更多功能的特殊互斥锁类型 锁定可能性比普通互斥锁。有时,我们可以 区分读取数据和修改数据。如果只是 一些线程需要修改数据,并使用普通的互斥锁 保护数据不受并发访问的影响,并发性非常好 有限:只读取数据的两个线程将被序列化 而不是同时执行。
如果我们允许并行访问只读取数据的线程但是 我们避免读取和修改的线程之间的并发访问 在修改的线程之间,我们可以提高性能。这是 特别适用于数据读取比较常见的应用程序 数据修改和同步数据读取代码需要一些 时间执行。使用可共享的互斥锁,我们可以获得2种锁定类型:
独占锁:类似于普通的互斥锁。如果一个线程获得了 独占锁定,没有其他线程可以获得任何锁定(独占或 其他)直到独占锁被释放。如果其他任何线程有 任何除独占之外的锁,一个试图获得独家的线程 锁将阻止。这个锁将由线程获取 修改数据。可共享锁:如果线程获得可共享锁, 其他线程无法获得独占锁。如果有任何线程 获得了一个试图获得可共享锁的线程的独占锁 会阻止。此锁定由只需要读取的线程执行 数据。使用可升级的互斥锁,我们可以获得以前的锁定加 一个新的可升级锁:
可升级锁定:获取可升级锁定与获取类似 特权共享锁。如果一个线程获得了一个可升级的锁, 其他线程可以获得可共享的锁。如果有任何线程已获得 一个线程尝试获取的独占或可升级锁定 可升级锁将阻止。获得可升级的线程 锁,保证能够原子地获得一个独占锁 当获得可共享锁的其他线程释放它时。这个 用于可能需要修改数据的线程,但通常 只需要读取数据。该线程获取可升级锁 和其他线程可以获得共享锁。如果可升级 线程读取数据,它必须修改它,线程可以 提升获得独占锁:当所有可共享的线程都有 发布了可共享锁,可升级锁被原子升级 独家锁定。新提升的线程可以修改数据 并且可以肯定没有其他线程在执行时修改它 过渡。只有1个线程可以获得可升级(特权 读者)锁定。 boost interprocess docs
C ++本身还没有reader-writer locks
(使用共享的互斥锁)但@Howard Hinnet确实尝试将它们放在那里,如果你看here他也提供了代码
C ++没有信号量,就我所知,互斥量只在新的C ++ 11标准中,这导致了为什么大部分都是关于boost::interprocess