《C#程序设计pp8.ppt》由会员分享,可在线阅读,更多相关《C#程序设计pp8.ppt(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、nC#程序设计pp8第8章 C#的多线程 C#和.NET类库为开发多线程应用程序提供了支持,本章首先介绍线程的概念、工作方式、优先级等,然后介绍线程同步的相关知识,最后论述线程同步时会出现的问题。学习完本章,就可以使用多线程技术来提高程序效率了。C#C#的多线程的多线程本章结构本章结构8.1 线程的概念8.2 线程的优先级8.3 线程的同步8.4 线程开发实例8.1 8.1 线程的概念线程的概念 使用C#编写任何程序时,都有一个入口Main()方法。程序从Main()方法的第1条语句开始执行,直到这个方法返回为止。这样的程序结构非常适合于有一个可识别的任务序列的程序,但该程序常常需要同时完成多
2、个任务。在C#应用程序中,第1个线程总是Main()方法,因为第1个线程是由.NET运行库开始执行的,Main()方法是.NET运行库选择的第1个方法。后续的线程由应用程序在内部启动,即应用程序可以创建和启动新的线程。8.1 8.1 线程的概念线程的概念8.1.1 多线程工作方式多线程工作方式8.1.2使用多线程的时机使用多线程的时机8.1 8.1 线程的概念线程的概念8.1.1 多线程工作方式多线程工作方式v所谓抢先式多任务处理,是指所谓抢先式多任务处理,是指WindowsWindows在某个进程中选择一个线程,该线在某个进程中选择一个线程,该线程运行一小段时间。这个时间非常短,不会超过几毫
3、秒。这段很短的时程运行一小段时间。这个时间非常短,不会超过几毫秒。这段很短的时间称为线程的时间片(间称为线程的时间片(time slicetime slice)。过了这个时间片以后,)。过了这个时间片以后,WindowsWindows就收回控制权,选择下一个被分配了时间片的线程。这些时间片非常短,就收回控制权,选择下一个被分配了时间片的线程。这些时间片非常短,用户可以认为许多事件是同时发生的。用户可以认为许多事件是同时发生的。8.1 8.1 线程的概念线程的概念8.1.1 多线程工作方式多线程工作方式n即使应用程序只有一个线程,抢先式多任务处理的进程也在进行,因为系即使应用程序只有一个线程,抢
4、先式多任务处理的进程也在进行,因为系统上运行了许多其他进程,每个进程都需要一定的时间片来完成其线程统上运行了许多其他进程,每个进程都需要一定的时间片来完成其线程.当当屏幕上有许多应用程序窗口时,每个窗口都代表不同的进程,可以单击它屏幕上有许多应用程序窗口时,每个窗口都代表不同的进程,可以单击它们中的任意一个,让它显示响应。这种响应不是即时的,在相关进程中下们中的任意一个,让它显示响应。这种响应不是即时的,在相关进程中下一个负责处理该窗口的用户输入的线程得到一个时间片时,这种响应才会一个负责处理该窗口的用户输入的线程得到一个时间片时,这种响应才会发生。如果系统非常忙,就需等待,但这种等待的时间非
5、常短暂,用户不发生。如果系统非常忙,就需等待,但这种等待的时间非常短暂,用户不会觉察到。会觉察到。8.1 8.1 线程的概念线程的概念8.1.2使用多线程的时机使用多线程的时机v应用多线程技术最大的误区是在没有分清何时使用多线程的情况下就盲目使用多线程。除非使用多处理计算机,否则在CPU密集的任务中使用两个线程是不能节省多少时间的,理解这一点很重要。v使用多线程有下面两个优点:可以及时对用户操作作出响应,因为一个线程在处理用户输入时,另一个线程在后台完成其他工作,本章开始时所举的拼写检查和打印的例子就是典型的适合使用多线程技术的应用;如果一个或多个线程所处理的工作不占用CPU时间,则可以节省时
6、间,例如,在网络应用开发中让一个线程等待从Internet中获取数据,同时其他线程可以继续处理其他的事务。8.2 线程的优先级线程的优先级v一般情况下,如果有优先级较高的线程在工作,就不会给优先级较一般情况下,如果有优先级较高的线程在工作,就不会给优先级较低的线程分配任何时间片,其优点是可以保证给接收用户输入的线低的线程分配任何时间片,其优点是可以保证给接收用户输入的线程指定较高的优先级。在大多数的时间内,这个线程什么也不做,程指定较高的优先级。在大多数的时间内,这个线程什么也不做,而其他线程则执行它们的任务,一旦用户输入了信息,这个线程就而其他线程则执行它们的任务,一旦用户输入了信息,这个线
7、程就立即获得比应用程序中其他线程更高的优先级,在短时间内处理用立即获得比应用程序中其他线程更高的优先级,在短时间内处理用户输入信息。户输入信息。8.2 线程的优先级线程的优先级名名 称称含含 义义Highest将线程安排在具有任何其他优先级的线程之前AboveNormal将线程安排在具有Highest优先级的线程之后,在具有Normal优先级的线程之前Normal将线程安排在具有AboveNormal优先级的线程之后,在具有BelowNormal优先级的线程之前。默认情况下,线程具有Normal优先级BelowNormal将线程安排在具有Normal优先级的线程之后,在具有Lowest优先级的
8、线程之前Lowest将线程安排在具有任何其他优先级的线程之后 线程的优先级定义为线程的优先级定义为ThreadPriorityThreadPriority枚举类型,取值如下表所示:枚举类型,取值如下表所示:8.3 线程的同步线程的同步v所谓线程同步,是指在某一时刻只有一个线程可以访问变量。如果所谓线程同步,是指在某一时刻只有一个线程可以访问变量。如果不能确保对变量的访问是同步的,就可能会产生错误或不可预料的不能确保对变量的访问是同步的,就可能会产生错误或不可预料的结果。一般情况下,当一个线程写入一个变量,同时有其他线程读结果。一般情况下,当一个线程写入一个变量,同时有其他线程读取或写入这个变量
9、时,就应同步该变量。本节简要线程同步的相关取或写入这个变量时,就应同步该变量。本节简要线程同步的相关知识。知识。8.3 线程的同步线程的同步8.3.1同步的含义同步的含义8.3.2在在C#中处理同步中处理同步8.3.3同步时要注意的问题同步时要注意的问题v同步问题产生的同步问题产生的原因原因是:在高级语言的源代码中,大多数情况下看起来是是:在高级语言的源代码中,大多数情况下看起来是一条语句的语句,在后面编译的过程中会被翻译为多条汇编语言机器代码,一条语句的语句,在后面编译的过程中会被翻译为多条汇编语言机器代码,从而该语句在操作系统调度时被划分到不同的时间片中。从而该语句在操作系统调度时被划分到
10、不同的时间片中。v同步问题只发生在下述场合中:至少有一个线程要写入一个变量,与此同同步问题只发生在下述场合中:至少有一个线程要写入一个变量,与此同时,其他线程正在读取或写入同一个变量。时,其他线程正在读取或写入同一个变量。8.3 线程的同步线程的同步8.3.1同步的含义同步的含义n 通过对指定对象加锁和解锁可以同步代码段的访问。在通过对指定对象加锁和解锁可以同步代码段的访问。在.NET的的System.Threading命名空间中提供了命名空间中提供了Monitor类来实现加锁与解锁。这个类类来实现加锁与解锁。这个类中的方法都是静态的,所以不需要实例化这个类。这些静态方法提供了一种中的方法都是
11、静态的,所以不需要实例化这个类。这些静态方法提供了一种机制,用来同步对象的访问,从而避免死锁和维护数据的一致性。机制,用来同步对象的访问,从而避免死锁和维护数据的一致性。8.3 线程的同步线程的同步8.3.2在在C#中处理同步中处理同步Monitor类的主要方法如下表所示:Monitor.Enter、Monitor.TryEnter和Monitor.Exit方法用来对指定的对象加锁和解锁。一旦某个线程获取(调用了Monitor.Enter方法)指定对象(代码段)的锁,其他的线程都不能获取该锁。名名 称称含含 义义Enter在指定对象上获得排他锁TryEnter试图获取指定对象的排他锁Exit释
12、放指定对象上的排他锁Wait释放对象上的锁并阻塞当前线程,直到它重新获取该锁Pulse通知等待队列中的线程锁定对象状态的更改PulseAll通知所有的等待线程对象状态的更改8.3 线程的同步线程的同步8.3.2在在C#中处理同步中处理同步同步实例8.3 线程的同步线程的同步8.3.3同步时要注意的问题同步时要注意的问题n线程同步非常重要,但只在需要时使用也是非常重要的,因为使用线程同步会降低性能。降低性能的原因有两个:在对象上放置和解开锁会带来某些系统开销,但这些系统开销都非常小,线程同步使用得越多,等待释放对象的线程就越多。n如果一个线程在对象上放置了一个锁,需要访问该对象的其他线程就只能暂
13、停执行,直到该锁被解开才能继续执行。因此,在lock语句块内部编写的代码越少越好,以免出现线程同步错误。lock语句在某种意义上就是临时禁用应用程序的多线程功能,也就临时删除了多线程的各种优势。但是使用过多的同步线程的危险性(性能和响应降低)并没有在需要时不使用同步线程那么高(难以跟踪的运行时错误)。n死锁是一个错误,在两个线程都需要访问被互锁的资源时发生。8.3 线程的同步线程的同步8.3.3同步时要注意的问题同步时要注意的问题n在编写多线程应用程序时,如果需要同步,必须考虑代码的所有部分,检查是否有可能发生死锁的条件。必须记住:不可能预见不同线程遇到不同语句的确切时间。n在应用程序中,使用多线程时应仔细规划过多的线程会导致的资源问题,但同时线程不足又会使需要处理多任务的应用程序执行缓慢,执行效果也不好。虽然.NET Framework提供了处理线程的方法和机制,但并没有解决处理多线程中所有困难的任务,如必须考虑线程的优先级和同步问题。8.4 线程开发实例线程开发实例v【例8-2】使用两个线程显示计数。(参见课本Page 211-215)C#的多线程