已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
CLR对并行多线程的支持西安电子科技大学 韩进巍对于当今的分时操作系统而言,所有的任务都是以进程的形式完成的,进程的调度策略相当于兵法里面的谋略战法,如果把进程比喻成军事里面的将,那么线程就是兵。操作系统控制着计算机里的软硬件资源,组织计算机工作流程以及用户的交互,操作系统就是计算机世界里的军委主席,调兵遣将,决胜千里。当然,古代的操作系统还不用这么麻烦,因为古代计算机的资源实在有限,单任务操作系统都可以胜任,比如DOS,生产力的发展,资源的增加,在呼唤着更有效的资源管理分配机制,使得资源们可以发挥其作用,必然的,管理是需要成本的,管理机制本身不得不变得越来越复杂。进程的概念被引入到现代操作系统里之后,使得相互独立的应用程序对用户的响应可以宏观上并行化,更加有效的利用计算机资源。自然的,操作系统为用户给出了进程和线程相关的API,通过合理的应用这些操作系统特性,我们可以写出更有效的应用程序。现代的抽象编程语言,Java或.NET而非底层语言C,提供JVM、CLR这样的解释或编译支持,以及JDK,FCL这样的类库。抽象语言是对底层的抽象,对硬件和操作系统的API都应该有相应的映射,这使得程序员无需直接面对难以掌控的底层内存堆栈数据流等等东西。既然是一种抽象,当然,进程的概念就被完美的映射在了类库的空间里,类库对多线程有着完备的表达能力,运行时支持也可以实现这些抽象了的线程操作描述。本文就讲述.NET对多线程并行化的支持。FCL对该功能提供API,CLR对其做出支持,那么,我们通过对FCL基础类库为多线程并行功能提供的接口来回答题目的问题。首先简单的介绍一下.NET类库,FCL类库大约有7000个类,这些类被分成了几个部分,被包含在二十多个命名空间下。比如说Collections,Drawing,IO,Xml,Diagnostics,Text,Threading,ComponentModel,Runtime,Data等。其中加粗的字体的Threading包含在多线程并行要用到的类。然后我们回顾一下进程和线程的概念。说的白一点,正在执行的应用程序就是一个进程,对Window来说,进程是含有内存和资源并安置线程的地方。进程拥有的资源包括很多种类,在Windows里面,有文件句柄、线程、用户资源、GDI资源等等。进程往往是与某个任务挂钩。可以说,进程是一个带兵打仗的将军,军委主席操作系统将计算机资源交付给进程将军让进程去攻城略地。线程是进程将军的部下,线程是任务的实际执行者,军委主席和将军往往是坐镇指挥的,线程也有自己的资源线程内核是一个对象,还拥有一块1M左右的内核堆栈。操作系统调度管理进程,进程管理线程,有时也放心的让线程自我管理。现在我们跨出第一步,走近线程,实际上我们在平时编程时不太会去真正用到多线程的,因为虽然多线程是好 ,但是很难用好。具体说首先就是多线程编程比较复杂,我们习惯了的是一行一行的执行编程模式,对于好的多线程程序来说要避免这一点使得任务分隔在多个处理器核中,这就要考虑多个线程使用一个进程空间里的资源要考虑资源的一致性问题,其次,还有调试复杂的因素,线程间互相依赖,出了错很难复制情景,最后,平台相关,每台机器上的核心数不同,操作系统中还有很多其他进程,运行环境复杂也是一个因素。本文的思路会按照线程的基本操作、线程同步的基本手段、线程池的思想和应用、关于多线程和并行的简单总结。线程的基本操作包括线程的创建,线程的执行,线程的常用属性,线程的中断、线程的Join,变量的ThreadStatic特性。线程的创建使用如下方法:static void ThreadProc()/线程执行的内容,即委托方法thread t=new Thread(new ThreadStart(ThreadProc);/创建线程,构造线程对象t.start();/启动线程在构造线程对象的时候我们也可以用Lambda表达式,如下:thread t=new Thread() =Thread.Sleep(1000);/线程执行的内容放在此处,睡眠1000ms);/创建线程,构造线程对象,将Lambda表达式传入构造方法t.start();/启动线程如果需要为线程传参则如下:(另外还说明了另一种启动线程的方式)new Thread(date) =/将date转换为日期时间类型Console.WrtieLine(DateTime)date).ToString();).Start(DateTime.Now);/没有构造出的线程对象找标识符,创建出线程后立马调用了Start方法,并在Start中传入当前的参数。有个问题,就是传入的参数只能是一个,不支持多个参数,因此如果要参多个参数要自定义一个对象,包进去再拆出来。此外还可以使用一个无参方法来包装线程方法主体:/由Lambda表达式传入的方法没有参数,因此=前的括号内无参,但是里/面封进去了Sub函数是由两个参数的new Thread()=Sub(6,2).start();static void Sub(int i,int j)Console.WriteLine(i-j);前台后台IsBackground属性,前台后台是Thread对象的一个属性,IsBackground属性默认是true,即前台线程,相对的进程池里的是后台线程,后面提到。后台线程会随着主线程的结束而结束,而前台线程,应用程序需要等到前台线程结束后才会结束。比如看下面一段代码:new Thread()=Console.ReadLine()IsBackground=false;.Start();主线程很容易就能执行完毕,但是新线程里面的ReadLine需要等待往控制台里输入内容和回车后才能结束。上面一段代码并没有因为有ReadLine方法而继续等待输入,而是直接就结束了,但是保持默认的true属性的话,就会一直等回车的输入。优先级Priority属性。高优先级的线程会执行得快一点。但也不是非常大的区别,低优先级的进程依然有很多机会被执行。IsAlive属性用来指示线程的运行状态,比如可以这样中止掉一个线程。if(t.IsAlive) t.Abort();/中止方法。线程的中断可以通过使用该线程的Abort方法,并且可以传入描述中断状态的字符串,线程被中断时可以在内部捕获ThreadAbortException,并接收中断的描述字符串。例如:Thread t=new Thread()=/用try catch块捕捉中断trywhile(true)/正常情况下会每隔一秒输出一次RunningConsole.WriteLine(“Running”);Thread.Sleep(1000);catch(ThreadAbortException abortException)/被Abort后可以接收中断字符串Console.WriteLine(string)abortException.ExceptionState);).Start();/运行3秒多后,输出三次RunningThread.Sleep(3100);/接收中断,输出Wrongt.Abort(“Wrong!”);Thread(100);/s输出已经结束的线程的状态Console.WriteLine(t.ThreadState);线程的Join,线程创建后会在四个状态之间改变:Unstart、Running、WaitSleepJoin、Stopped。WaitSleepJoin相当于阻塞,Join方法最难理解,在A线程中调用B.Join()就相当A对B说:B你快点做,做完了我好做,我现在先停下等你。Join要么不带参数,要么带一个时间参数意味着,A对B说我只等你这么久,超过了我就不等了先走了。如下例子:Console.WriteLine(“主线程开始:”);/创建的新线程开始后要执行1000ms才结束Thread t=new Thread()=Console.WriteLine(“新线程开始执行”);Thread.Sleep(1000););t.Start()/主线程停下来,希望在2000秒能看到t结束,然后再执行自己if(t.Join(2000)/若主线程的目的达到了,返回一个true,意味着t在2000ms内结束了Console.WriteLine(“新线程结束”);else/若主线程目的没达到,返回false,意味着t2000ms内没结束,/主线程等不及了先走了Console.WriteLine(“Join超时”);Console.WriteLine(“主线程结束”);ThreadStatic字段是用来描述静态变量的,也就是说,加上了这个描述的静态变量可以做到线程独立访问,就像有两个这个变量一样。比如:/ ThreadStaticstatic int i;new Thread()=for(int k=0;kfor(int j=0;j lock(locker)/lock关键字决定,/两个线程不能同时执行由相同锁对象标志的代码段/子线程的有效代码是要睡1000msThread.Sleep(1000);).Start();/进入主线程后主线程的有效代码也是睡1000ms/如果没有lock,这两个线程各自执行,一共需要1000ms就会结束。/然而他们有相同的locker对象,locker让lock段的代码不得同时执行/也就是最后要1000mslock(locker)Thread.Sleep(1000);Console.WriteLine(sw.ElapseMilliseconds);最后输出2000,主线程和新线程尽管同时开始然却没有同步进行,是一个接一个进行的,这就是lock的用法。我们知道,同步的对象除了对代码指令进行同步,还有对数据块的同步,(如i+十万二十万次的例子),那么,数据的同步是如何用lock体现的呢?依然使用i+十万次和二十万次的例子static int i;/这里的i不用线程静态特性Static object locker = new object();new Thread()=for(int k=0;kfor(int j=0;j/读进程while(true)are.WaitOne();/等待,直到are上有信号Console.WriteLine(“读到的是: 0”,k);/因为这个对象会AutoReset,所以执行完WaitOne的时候are上已经没/有信号了).Start();/主进程是写进程for(int k=0;j100;k+)Console.WriteLine(“写入的值是: 0”,k);i=k;are.Set();/此时,i上已经有有效值,可以通知读进程去读了Thread.Sleep(1);/睡一毫秒让他读th.Abort();/最后终止读线程,也就终止了应用程序。WaitAll实际上很好理解,就是在对象数组的标识符上调用,意思是等待所有的对象元素都被赋予了信号才能往下走,就不再详细叙述。WaitAny也是一样。线程池的思想和应用。为什么要有线程池呢?因为线程在系统的创建和销毁的成本非常大,不仅要分配给他资源,还要在线程间来回切换。为了解决频繁的创建和销毁线程带来的开销问题,.NET给出了线程池,也就是系统自己维护的一些线程,起到缓冲作用,当新申请线程时,不需要真正的从无到有创建一个线程,而是从线程池里拿出一个,将用户的任务委托给他即可。本质非常简单,类似于钱包里的现金,不需要每次花钱的时候都去银行取钱,小额支付从钱包(线程池)里拿就可以。从线程池中得到的线程一但用完,不会被立即销毁,而是放回线程池里以备下一次的征用。其实之所以使用线程池是不希望线程在创建后运行结束后理解回收,这样的话以后要用的时候还需要创建,我们可以让线程池至少保留几个线程,即使没有线程在工作也保留。线程池里的线程默认为后台线程,意味着当所有的前台线程都退出后,后台线程会关闭。线程池由ThreadPool实现,通过向他的QueueUserWorkItem方法里传一个委托实例即可实现使用线程池中的任务。委托实例的类是WaitCallBack,通过传入处理方法实现委托实例的构造。下面我们看一个例子,抽象了OfficeWord的“拼写检查”“打印文档”“检查更新”三大独立线程实现的功能。class OfficeWordprivate void Check()Console.WriteLine(“正在检查更新”);private void Print()Console.WriteLine(“正在打印文档”);private void Update()Console.WriteLine(“正在检查更新”);private void NormalWork()/其他正常代码/这里开始从线程池中抽调待用的线程,给与相应的委托方法,/让其执行,用线程执行的方法去实例化一个委托对象,/用线程池接收到委托对象后自动安排线程处理ThreadPool.QueueUserWorkItem(new WaitCallBack(this.Check);ThreadPool.QueueUserWorkItem(new WaitCallBack(this.Print);ThreadPool.QueueUserWorkItem(new WaitCallBac
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 保险公司理赔部理赔流程与服务质量提升
- 农场内部检查制度范本
- 制定内部管理规章制度
- 员工内部培训制度
- 团播内部规章制度
- 园林所内部管理制度
- 天保工程内部审计制度
- 如何内审内部控制制度
- 子公司内部财务制度
- 汽车内部安全保卫制度
- 三年级下册除法列竖式计算题500道
- 2025下半年教师资格考试新版试卷真题附答案(高中体育与健康)
- 兴趣班自愿报名协议书
- 水池带顶拆除施工方案
- 研究生工作站管理办法
- 脑转移瘤综合治疗策略
- 2025年工勤人员转岗考试题库
- 基孔肯雅热诊疗方案课件
- 广东省汕头市2026届高考第一次模拟考试英语试题
- DBJ51T2482024四川省城镇管道燃气安全隐患分类和分级标准
- 超声引导下小儿骶管阻滞麻醉技术
评论
0/150
提交评论