`
ajuanlong
  • 浏览: 107750 次
社区版块
存档分类
最新评论

秒杀多线程第七篇 经典线程同步 互斥量Mutex

 
阅读更多

阅读本篇之前推荐阅读以下姊妹篇:

秒杀多线程第四篇一个经典的多线程同步问题

秒杀多线程第五篇经典线程同步关键段CS

秒杀多线程第六篇经典线程同步事件Event

前面介绍了关键段CS事件Event经典线程同步问题中的使用。本篇介绍用互斥量Mutex来解决这个问题。

互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问。互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源。使用互斥量Mutex主要将用到四个函数。下面是这些函数的原型和使用说明。

第一个 CreateMutex

函数功能:创建互斥量(注意与事件Event的创建函数对比)

函数原型:

HANDLECreateMutex(

LPSECURITY_ATTRIBUTESlpMutexAttributes,

BOOLbInitialOwner,

LPCTSTRlpName

);

函数说明:

第一个参数表示安全控制,一般直接传入NULL

第二个参数用来确定互斥量的初始拥有者。如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,由于该线程ID非零,所以互斥量处于未触发状态。如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,这意味互斥量不为任何线程占用,处于触发状态。

第三个参数用来设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。

函数访问值:

成功返回一个表示互斥量的句柄,失败返回NULL

第二个打开互斥量

函数原型:

HANDLEOpenMutex(

DWORDdwDesiredAccess,

BOOLbInheritHandle,

LPCTSTRlpName //名称

);

函数说明:

第一个参数表示访问权限,对互斥量一般传入MUTEX_ALL_ACCESS。详细解释可以查看MSDN文档。

第二个参数表示互斥量句柄继承性,一般传入TRUE即可。

第三个参数表示名称。某一个进程中的线程创建互斥量后,其它进程中的线程就可以通过这个函数来找到这个互斥量。

函数访问值:

成功返回一个表示互斥量的句柄,失败返回NULL

第三个触发互斥量

函数原型:

BOOLReleaseMutex (HANDLEhMutex)

函数说明:

访问互斥资源前应该要调用等待函数,结束访问时就要调用ReleaseMutex()来表示自己已经结束访问,其它线程可以开始访问了。

最后一个清理互斥量

由于互斥量是内核对象,因此使用CloseHandle()就可以(这一点所有内核对象都一样)。

接下来我们就在经典多线程问题用互斥量来保证主线程与子线程之间的同步,由于互斥量的使用函数类似于事件Event,所以可以仿照上一篇的实现来写出代码

运行结果如下图:

可以看出,与关键段类似,互斥量也是不能解决线程间的同步问题。

联想到关键段会记录线程ID即有“线程拥有权”的,而互斥量也记录线程ID,莫非它也有“线程拥有权”这一说法。

答案确实如此,互斥量也是有“线程拥有权”概念的。“线程拥有权”在关键段中有详细的说明,这里就不再赘述了。另外由于互斥量常用于多进程之间的线程互斥,所以它比关键段还多一个很有用的特性——“遗弃”情况的处理。比如有一个占用互斥量的线程在调用ReleaseMutex()触发互斥量前就意外终止了(相当于该互斥量被“遗弃”了),那么所有等待这个互斥量的线程是否会由于该互斥量无法被触发而陷入一个无穷的等待过程中了?这显然不合理。因为占用某个互斥量的线程既然终止了那足以证明它不再使用被该互斥量保护的资源,所以这些资源完全并且应当被其它线程来使用。因此在这种“遗弃”情况下,系统自动把该互斥量内部的线程ID设置为0,并将它的递归计数器复置为0,表示这个互斥量被触发了。然后系统将公平地选定一个等待线程来完成调度(被选中的线程的WaitForSingleObject()会返回WAIT_ABANDONED_0)。

下面写二个程序来验证下:

第一个程序创建互斥量并等待用户输入后就触发互斥量。第二个程序先打开互斥量,成功后就等待并根据等待结果作相应的输出。详见代码:

第一个程序:

第二个程序:

运用这二个程序时要先启动程序一再启动程序二。下面展示部分输出结果:

结果一.二个进程顺利执行完毕:

结果二.将程序一中//exit(0);前面的注释符号去掉,这样程序一在触发互斥量之前就会因为执行exit(0);语句而且退出,程序二会收到WAIT_ABANDONED消息并输出“拥有互斥量的进程意外终止”:

有这个对“遗弃”问题的处理,在多进程中的线程同步也可以放心的使用互斥量。

最后总结下互斥量Mutex

1.互斥量是内核对象,它与关键段都有“线程所有权”所以不能用于线程的同步。

2.互斥量能够用于多个进程之间线程互斥问题,并且能完美的解决某进程意外终止所造成的“遗弃”问题。

下一篇《秒杀多线程第八篇 经典线程同步 信号量Semaphore》将介绍使用信号量Semaphore来解决这个经典线程同步问题。

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7470936

如果觉得本文对您有帮助,请点击支持一下,您的支持是我写作最大的动力,谢谢。


分享到:
评论

相关推荐

    linux上实现多进程和多线程实现同步互斥(源代码)

    在Linux操作系统中,多进程和多线程是两种并发执行的方式,它们在处理并发问题时,经常需要进行同步和互斥操作,以确保数据的一致性和程序的正确性。本篇将详细介绍这两种并发模型以及如何在Linux环境中实现同步互斥...

    C# 多线程的同步与互斥(使用Mutex和Event)

    当多个线程同时运行时,可能会引发数据竞争和不一致性问题,因此理解和掌握线程的同步与互斥至关重要。在给定的标题和描述中,我们关注的是如何利用Mutex和AutoResetEvent这两个类来解决这些问题。 Mutex(互斥锁)...

    解决多线程编程中的同步互斥问题

    但是需要注意的是,关键段仅能解决单个CPU核心上的互斥访问问题,对于多处理器或多核心环境下的同步问题可能需要采用更高级别的同步机制,如互斥锁(Mutex)或信号量(Semaphore)等。此外,虽然本示例代码展示了...

    C# 多线程同步与互斥,使用Mutex和AutoResetEvent类

    在C#编程中,多线程同步和互斥是并发编程中的关键概念,它们用于确保在多线程环境中数据的一致性和程序的正确性。Mutex(互斥锁)和AutoResetEvent(自动重置事件)是.NET框架提供的两种工具,用于解决这些问题。 ...

    多线程编程和操作系统线程同步互斥演示

    在这个“多线程编程和操作系统线程同步互斥演示”中,作者可能创建了一个或多个人工场景,展示了如何在VC++环境中使用多线程,并且演示了线程同步和互斥的实践应用。这可能涉及到以下几个方面: 1. **线程创建**:...

    Linux线程同步之互斥量(mutex).pdf

    总结来说,Linux下的互斥量是实现线程同步的必备工具,通过简单的API调用,开发者可以实现复杂的多线程同步逻辑,保证程序的稳定运行。在实际应用中,通过案例分析和不断实践,可以更加深入地理解和掌握互斥量的使用...

    使用互斥对象(Mutex)实现线程同步

    在多线程编程中,线程同步是一种至关重要的技术,它确保了多个线程在访问共享资源时的正确性,防止数据竞争和不一致状态的发生。互斥对象(Mutex)是实现线程同步的一种常见机制,尤其在MFC(Microsoft Foundation ...

    Mutex 互斥量使用实例

    互斥量(Mutex)是Windows操作系统中的一个同步对象,用于控制多个线程对共享资源的访问,确保在任何时刻只有一个线程能访问该资源。在多线程编程中,互斥量是保证数据一致性、避免数据竞争的重要工具。本实例将深入...

    windows多线程的同步和互斥

    然而,多线程环境下可能会出现数据竞争、死锁等问题,因此需要使用同步和互斥机制来保证线程安全。 一、线程同步 线程同步是指在多线程环境中,控制多个线程按特定顺序执行或协同工作的一种机制。常见的线程同步...

    利用Mutex互斥变量实现线程同步机制

    总结来说,Mutex互斥变量是实现线程同步的重要工具,它通过控制对共享资源的访问,确保了在多线程环境下的数据一致性。在实际编程中,我们需要合理使用Mutex来避免竞态条件和死锁等问题,同时注意异常处理和资源管理...

    Linux线程同步之互斥量(mutex)[收集].pdf

    互斥量,或互斥锁,是实现线程同步的一种基础工具,它确保同一时间只有一个线程能访问受保护的临界区。在Linux中,互斥量遵循POSIX线程标准,并通过`pthread`库来实现。 互斥量的类型为`pthread_mutex_t`,在`...

    利用互斥实现多线程同步

    互斥量是实现多线程同步的有效工具,能确保共享资源在同一时间仅被一个线程访问。在实际开发中,正确地使用互斥量可以预防数据竞争,保证程序的正确性和性能。然而,过度使用或设计不当的互斥量可能导致不必要的阻塞...

    VC++6.0下利用互斥量同步线程来实现文件读取进度条C++源代码程序小实例

    在本文中,我们将深入探讨如何在VC++6.0环境下使用互斥量(Mutex)同步线程,以实现文件读取进度条的功能。这是一项在多线程编程中常见的任务,尤其是在开发用户界面丰富的应用程序时,为了提供更好的用户体验,我们...

    vc++ multithread多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区

    本教程将深入探讨四种常见的线程同步机制:事件对象、信号量、互斥量以及临界区,帮助开发者理解和掌握如何在VC++中安全地实现多线程通信。 一、事件对象 事件对象是Windows API中用于线程间通信的一种同步机制。它...

    使用信号量和关键段实现多线程的同步与互斥

    C++11引入了多线程支持,通过`<thread>`库创建和管理线程,`<mutex>`库提供了互斥量和其他同步原语。在这个项目中,`std::thread`将被用来创建读者和写者的线程,`std::mutex`用于互斥访问,可能还会用到`std::...

    实例讲述线程的同步互斥

    线程的同步互斥是多线程编程中的关键概念,主要用来解决并发执行时的数据安全问题。在Java、C++、Python等支持多线程的编程语言中,线程同步和互斥是确保程序正确性和数据一致性的重要手段。 线程是指在单一进程内...

    C#的多线程示例;几个多线程之间的互斥,同步;WPF主界面INVOKE

    本文将深入探讨C#中的多线程机制,包括线程互斥与同步,以及如何在WPF主界面中安全地更新UI。 首先,让我们理解什么是多线程。多线程是指一个应用程序内同时运行多个独立的执行线程。在C#中,可以使用`System....

    linux上互斥线程Mutex的代码及解释

    在多线程编程中,互斥量(Mutex)是一种常见的同步机制,用于防止多个线程同时访问共享资源,从而避免数据竞争和不一致状态的发生。本文将深入探讨Linux环境下C++互斥线程Mutex的使用方法,通过解析示例代码,帮助...

Global site tag (gtag.js) - Google Analytics