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

关于C#中AutoResetEvent和ManualResetEvent的一点学习心得

 
阅读更多

C#中的AutoResetEvent和ManualResetEvent用于实现线程同步。其基本工作原理是多个线程持有同一个XXXResetEvent,在这个XXXResetEvent未被set前,各线程都在WaitOne()除挂起;在这个XXXResetEvent被set后,所有被挂起的线程中有一个(AutoResetEvent的情况下)或全部(ManualResetEvent的情况下)恢复执行。

AutoResetEvent与ManualResetEvent的差别在于某个线程在WaitOne()被挂起后重新获得执行权时,是否自动reset这个事件(Event),前者是自动reset的,后者不是。所以从这个角度上也可以解释上段提到的“在这个XXXResetEvent被set后,所有被挂起的线程中有一个(AutoResetEvent的情况下)或全部(ManualResetEvent的情况下)恢复执行”——因为前者一旦被某个线程获取后,立即自动reset这个事件(Event),所以其他持有前者的线程之后WaitOne()时又被挂起;而后者被某个获取后,不会自动reset这个事件(Event),所以后续持有后者的线程在WaitOne()时不会被挂起。

set是让事件(Event)发生,而reset是让事件(Event)复位或者说忽略已经的事件(Event)。WaitOne是等待事件(Event)的发生,之后继续向下执行,否则一直等待。

在构造AutoResetEvent和ManualResetEvent的时候,它们的构造方法里需要一个参数initState,中文版MSDN(2005和2008)上的解释是“若要将初始状态设置为终止,则为 true;若要将初始状态设置为非终止,则为 false。”,我看了一个下午,没弄明白,而看一下英文版后大概就明白了“A value that you set totrueto set the initial state of the specified event to signaled. Set this value tofalseto set the initial state of the event to nonsignaled.”(参见:http://msdn.microsoft.com/en-us/library/ee432364.aspx),大体意思是说这个参数决定是否在构造这个Event的时候就设置它为“发生”状态(signaled),如果是,则设置为true,也就是说持有这个Event的一个或多个线程在一开始就可以执行,而不需要挂起,至少是不会全部挂起(持有AutoResetEvent的一个或多个线程在任意时刻至多有一个线程在执行;持有ManualResetEvent的一个或多个线程会同时执行),否则为false(持有AutoResetEvent和ManualResetEvent的所有线程都将挂起,因为事件(Event)没有被set,即事件没有发生)。

另外稍微提一下,我在做多线程测试的时候,发现在线程数少的情况下,即使多个线程不做任何同步,如果对一个公共变量进行非互斥式修改时,不会至少很难出现不一致的情况,比如开100个线程,这个线程不做任何同步就分别给一个公共变量执行加1操作,那么结果在绝绝绝大部分的情况下是100!所以,我最后就下了狠心,把线程数增加到1000个,这个时候才出现问题,但问题也不是想象得那么严重——结果在991-1000之间!

再有,MSDN上对Monitor的Wait和Pulse两个方法用法的举例会导致死锁,一种死锁的执行顺序是:

1、线程tSecond在SecondThread()中执行到while(Monitor.Wait(m_smplQueue,1000))后,释放m_smplQueue的锁,线程tSecond挂起;

2、线程tFirst在FirstThread()中执行到Monitor.Wait(m_smplQueue)之前耗费的时间超过1000毫秒,此时线程tSecond退出,线程tFirst挂起,并且从此以后不会被恢复!

可以使用如下改动过的代码验证:

分享到:
评论

相关推荐

    C#-【多线程篇】AutoResetEvent和ManualResetEvent的区别(中级)

    引入命名空间: using System.Threading; AutoResetEvent: autoResetEvent.WaitOne();//运行完后,**自动将事件...ManualResetEvent: manulResetEvent.WaitOne();//运行完后,**不会自动将事件状态设置为无信号**

    AutoResetEvent_Examples.zip_AutoResetEvent_ManualResetEvent

    通过学习这些示例代码,开发者可以深入理解如何在实际项目中运用 `AutoResetEvent` 和 `ManualResetEvent`,以提高多线程程序的效率和正确性。在进行多线程编程时,熟练掌握这些同步机制对于避免竞态条件、死锁等...

    C#线程同步ManualResetEvent

    总之,`ManualResetEvent`是C#中进行线程同步的重要工具,它提供了灵活的控制机制,使得开发者能够有效地管理和协调多线程程序的行为。通过理解和熟练运用,我们可以编写出更稳定、高效的多线程应用。

    C#线程同步AutoResetEvent

    在C#编程中,线程同步是一个至关重要的概念,特别是在多线程环境下,它用于控制多个线程对共享资源的访问,确保数据的一致性和程序的正确性。本篇文章将详细探讨`AutoResetEvent`这一线程同步工具,并通过一个DEMO来...

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

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

    C# 多线程同步、异步_AutoResetEvent用法

    在Visual Studio 2008中,创建多线程项目时,可以选择"新建项目"->"Visual C#"->"Windows应用程序",然后在代码中引入`System.Threading`命名空间,即可使用`AutoResetEvent`进行多线程同步和异步操作。 总结,`...

    C#使用AutoResetEvent实现同步

    前几天碰到一个线程的顺序...原来,AutoResetEvent在.Net多线程编程中经常用到。当某个线程调用WaitOne方法后,信号处于发送状态,该线程会得到信号, 程序就会继续向下执行,否则就等待。而且 AutoResetEvent.WaitOne

    详细解析C#多线程同步事件及等待句柄

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading....

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

    Mutex和AutoResetEvent只是C#中众多同步原语的一部分,还包括Semaphore、Monitor、SemaphoreSlim等。理解并熟练使用这些工具,可以帮助开发者避免数据竞争,提高程序的并发性能,以及实现更复杂的线程交互逻辑。在...

    ManualResetEvent继续等待.rar

    在本文中,我们将深入探讨ManualResetEvent的原理、使用方法以及如何处理超时和继续等待的情况。 **ManualResetEvent介绍** ManualResetEvent是System.Threading命名空间下的一个类,它继承自WaitHandle。它的主要...

    C# 中的 多线程 C# 多线程

    C#提供了一些机制,如`AutoResetEvent`、`ManualResetEvent`、`CountdownEvent`和`Barrier`,用于线程间的信号传递和同步。 10. **线程安全的数据结构** .NET Framework 提供了一些线程安全的数据结构,如`...

    【C#】第二十一讲 C#中事件信号的使用.zip

    在C#编程中,事件和信号是用于处理对象间通信的关键机制。事件是当特定条件满足或特定操作发生时,一个对象(发送者)向另一个对象(接收者)发送的通知。信号则是事件的一种抽象,它允许对象之间进行异步通信。在本...

    C#多线程编程实战Code源代码

    在C#编程中,多线程技术是一种关键的并发处理机制,它允许程序同时执行多个独立的任务,...以上知识点在提供的源代码中都有具体的实现示例,通过学习和实践,你可以更好地掌握C#的多线程编程技巧,并应用于实际项目中。

    c#多线程学习代码资料

    这篇资料详细讲解了C#中的多线程使用方法,对于初学者来说是一份很好的学习资源。 多线程的基本概念: 1. **线程**:线程是程序执行的最小单元,每个线程都有自己的执行顺序和独立的内存空间。 2. **主线程**:每个...

    c# 多线程学习

    C#引入了`ManualResetEvent`、`AutoResetEvent`、`Mutex`、`Semaphore`和`Barrier`等同步原语,它们允许线程等待特定事件发生或同步执行。`WaitHandle`类是这些同步原语的基类,提供了`WaitOne`方法,使线程进入等待...

    多线程采集C#源代码

    在IT领域,多线程是一种常见的编程技术,特别是在高性能计算和...在提供的压缩包文件中,"多线程采集C#源代码"可能包含这些技术的具体实现,通过阅读和分析这些代码,开发者可以学习和借鉴其中的设计模式和最佳实践。

    c#多线程编程实战(原书第二版)源码

    7. **线程通信**:`ManualResetEvent`、`AutoResetEvent`、`CountdownEvent`等工具用于线程间的通信和协调,源码中可能包含这些事件的用法。 8. **线程优先级**:尽管不推荐频繁设置,但`Thread.Priority`属性允许...

    使用WaitHandle 内含C#编写源代码

    在.NET框架中,`WaitHandle`是一个非常重要的抽象类,它是多线程编程中的关键组件。这个类提供了线程同步的能力,允许一个或多个线程等待特定...通过学习和实践提供的C#源代码,你可以进一步提升在并发编程领域的技能。

    C#打字游戏(关于多线程)

    通过分析和学习这个C#打字游戏项目,开发者可以深入了解多线程在实际项目中的应用,以及如何在C#中有效地管理线程,提升程序的性能和用户体验。同时,这也是对并发编程概念的实践,对于任何希望深入学习C#和系统级...

Global site tag (gtag.js) - Google Analytics