用互斥锁保护临界区

Posted

技术标签:

【中文标题】用互斥锁保护临界区【英文标题】:guarding a critical section with a mutex 【发布时间】:2012-08-16 20:15:15 【问题描述】:

假设我有一个共享对象,其中有一段代码受临界区保护,并且有多个线程正在访问该对象以进行读/写。当一个线程在临界区内时,其他线程正在等待。一旦线程退出 CS,操作系统就会允许访问任何等待的线程。

如果我仅限于一个进程,单独的CS是否对共享对象有很好的保护?

我问是因为我在网上看到正确的做法是使用内核对象(例如:互斥锁、信号机)来保护 CS。希望使用共享资源的线程需要首先使用 WaitForSingleObject 类型的函数获取互斥体/信号量。如果使用互斥体,则只有其中一个可以访问资源。一旦获得互斥锁,线程就会进入 CS,做应该做的事情,然后离开 CS 并释放互斥锁。然后操作系统允许任何其他等待线程获取互斥锁等等。

但不是和只使用 CS 一样吗?

此外,使用互斥锁应该比单独使用 CS 慢得多。我看到的仅使用 CS 的唯一问题是,如果线程在 CS 内部崩溃,那么其他线程可能永远无法访问共享资源。

还有什么其他原因可以说明这种方法更好吗? 提前谢谢

【问题讨论】:

这个应该转移到Computer Science吗? 我从未见过任何代码可以按照您所说的那样做。你能指出一些获取互斥量或信号量然后获取具有相同范围的临界区的代码吗?我怀疑您可能只是误读或误解了该代码,这就是您困惑的根源。 (您也可能会混淆术语“临界区”的两种不同用法。一种表示特定的同步原语,另一种表示受互斥锁同步保护的代码区域。) 谢谢david,我指的是CSection窗口结构(InitializeCS、EnterCS、LeaveCS、DeleteCS)。会不会是我误解了我读到的内容? Windows CriticalSection 是一个进程绑定的互斥体。它在一个过程中运行良好。不需要任何进一步的保护。 【参考方案1】:

听起来您在讨论某些特定于 Windows 的术语,而将其与一些通用计算机科学术语混为一谈。

在计算机科学中,术语“关键部分”用于必须以独占方式运行的代码区域(通常是由于数据共享)。在 Windows 中,有一个名为CRITICAL_SECTION 的同步对象可用于提供对执行区域的独占访问。 Windows 上CRITICAL_SECTION 对象的另一个属性是它仅限于在单个进程中使用。

在计算机科学中,术语“互斥锁”通常用于描述可用于在并行或当前执行线程之间提供同步的对象。在 Windows 中,还可以使用 CreateMutex() 函数创建一个互斥对象(它返回一个代表互斥的 HANDLE)。该对象可用于在相同或不同进程中的线程之间同步访问,因此可以在许多方面类似于CRITICAL_SECTION(但具有不同的API)使用它。如果你想同步不同进程中的执行线程,可以使用互斥对象,而CRITICAL_SECTION对象不能。

所以要回答您的问题(我认为),如果您只关心保护属于同一进程的线程之间的关键部分,那么 CRITICAL_SECTION 对象应该就足够了。可以改用互斥对象,但它的性能可能会稍差一些。应该不需要同时使用这两种类型的对象

【讨论】:

以上是关于用互斥锁保护临界区的主要内容,如果未能解决你的问题,请参考以下文章

临界区与互斥量区别

Unix网络编程-同步

锁、互斥和临界区之间的区别

临界区(critical section 每个线程中访问 临界资源 的那段代码)和互斥锁(mutex)的区别(进程间互斥量共享内存虚拟地址)

一文看懂临界区互斥锁同步锁临界区信号量自旋锁等名词!

互斥锁- pthread_mutex