《Inside C#》笔记(十三) 多线程 上

通过将一个任务划分成多个任务分别在独立的线程执行可以更有效地利用处理器资源并节省时间。但如果不合理地使用多线程,反而会带来种种问题并拖慢运行速度。

一 线程基础

a)线程与多任务

一个线程就是一个处理单元,多任务时多个线程会同时执行。多任务时会涉及到任务间的合作与优先级的问题。Windows NT内核的操作系统使用抢占多任务处理机制(preemptivemultitasking),系统会为每个线程划分出确定的执行时间(时间片),然后线程在给定的时间片内轮流执行。

在单核处理器上使用多线程时,线程只是被轮流执行,但给人的感觉好像是在同时执行;如果是在多核或者多个处理器上运行多线程,线程会真正同时运行。

b)上下文切换(Context Switching)

对于多线程来说,上下文切换是不可或缺的功能。当一个时间片被用完时处理器会发出中断信号,处理器将当前线程相关的内容保存到栈上,然后将下一个线程的相关内容从栈上读取到CONTEXT数据结构中,如果时间片用尽,又会切换CONTEXT中装载的线程。

c)多线程的使用

一个简单的多线程使用示例如下:

?

ThreadStartworker = new ThreadStart(WorkerThreadMethod);这样的写法在委托一章接触过,xvarName=new x (methodName)这样的形式表示初始化了一个x类型的委托,并指向methodName方法。

在实例化Thread时,必须传递ThreadStart类型的委托作为参数。调用Thread.Start方法后,ThreadStart指向的方法就会在另一个线程被执行。

二 System.Threading.Thread类

a)AppDomain(应用程序域)

AppDomain与win32进程有不少类似的地方,但在win32中,一个线程被限制在特定的进程中,不同进程间线程无法交互。而AppDomain中的线程可以跨域通信,或者调用其它AppDomain中的方法。所以,AppDomain相当于是在物理进程中的逻辑进程。

b)有两种方式可以拿到线程实例,一种是使用关键字new,另一种是使用Thread.CurrentThread取得正在执行的线程。可以使用Thread.Sleep方法来让线程挂起指定的时间,这个方法是静态的。如果为Thread.Sleep方法传递的参数为0,当前线程会主动释放尚未用完的时间片;如果为其传递Timeout.Infinite(值为-1的常量),那么当前线程会被无限期地暂停,直到有另一个线程对其实例调用Thread.Interrupt方法。Thread.Suspend方法也可以让线程挂起,但不是静态方法,要由另一个线程调用,与之配合的方法还有Thread.Resume。

c)Thread.Abort方法可以销毁线程,系统内部通过抛出ThreadAbortException异常来终止线程。ThreadAbortException比较特殊,是无法被捕获的。Abort后,线程不会立即停止,会等到将当前工作完成,达到”safe

point”后才退出。在多线程编程中,为了可靠地知道某个线程是否已终止,可以使用Thread.Join方法,这个方法直到线程被销毁后才返回。另外一旦线程被销毁,就无法被重新启动的。

学习资料:Inside C# by Tom Archer

时间: 2024-10-17 22:54:13

《Inside C#》笔记(十三) 多线程 上的相关文章

swift 笔记 (十三) —— 继承

继承 一个类可以从其它类继承方法,属性以及一些特征.被继承的类叫父类,那另一种就是子类了..这个我们都懂的.. 这是一个官方给的例子,它是一个基类(Base Class),因为它没有继承任何一个类,这个类里面有一个init方法,我们暂时忽略,只要知道这是个初始化方法,在我们创建一个类的实例的时候,这个方法会被执行,下一篇笔记会详细分析. class MyCar: Vehicle {          //继承的语法 init () {                              /

java之jvm学习笔记十三(jvm基本结构)

java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成图形,所以只要你有耐心,仔细,认真,并发挥你的想象力,这一章之后你会充满自信.当然,不是说看完本章,就对jvm了解了,jvm要学习的知识实在是非常的多.在你看完本节之后,后续我们还会来学jvm的细节,但是如果你在学习完本节的前提下去学习,再学习其他jvm的细节会事半功倍. 为了让你每一个知识点都有迹

《python源码剖析》笔记 python多线程机制

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.GIL与线程调度 Python中的线程是操作系统的原生线程,Python虚拟机使用一个全局解释器锁(Global Interpreter Lock)来互斥线程对Python虚拟机的使用 为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,所以引入了GIL. GIL:在一个线程拥有了解释器的访问权之后,其他的所有线程都必须等待它释放解释器的访问权,即使这些线程的下

linux网络编程学习笔记之四 -----多线程并发服务端

相对于使用进程实现并发,用线程的实现更加轻量.每个线程都是独立的逻辑流.线程是CPU上独立调度运行的最小单位,而进程是资源分配的单位.当然这是在微内核的操作系统上说的,简言之这种操作系统的内核是只提供最基本的OS服务,更多参看点击打开链接 每个线程有它自己的线程上下文,包括一个唯一的线程ID(linux上实现为unsigned long),栈,栈指针,程序计数器.通用目的寄存器和条件码,还有自己的信号掩码和优先级.同一个进程里的线程共享这个进程的整个虚拟地址空间,包括可执行的程序文本.程序的全局

Go语言学习笔记十三: Map集合

Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. Go语言中Map的写法比Java简单些,比Python繁琐. 定义Map var x map[string]string x : = make(map[string]string) 写法上有些奇怪,map为关键字,右侧中括号内部为key的类型,中括号外部为value的类型.一般情况下使用逗号或者冒号

学习笔记:Caffe上LeNet模型理解

学习笔记:Caffe上LeNet模型理解 Caffe中用的模型结构是著名的手写体识别模型LeNet-5(http://yann.lecun.com/exdb/lenet/a35.html).当年美国大多数银行就是用它来识别支票上面的手写数字的.能够达到这种商用的地步,它的准确性可想而知,唯一的区别是把其中的sigmoid激活函数换成了ReLU. 为什么换成ReLU,上一篇blog中找到了一些相关讨论,可以参考. CNN的发展,关键就在于,通过卷积(convolution http://deepl

[Nginx笔记]关于线上环境CLOSE_WAIT和TIME_WAIT过高

运维的同学和Team里面的一个同学分别遇到过Nginx在线上环境使用中会遇到TIME_WAIT过高或者CLOSE_WAIT过高的状态 先从原因分析一下为什么,问题就迎刃而解了. 首先是TIME_WAIT: 理解一下TIME_WAIT状态产生的原因,这个问题已经被很多很多的书说烂了,但是为什么很多人还是不能解决,究其原因还是因为 大多数都是学术派,并没有真正的遇到过这样的问题,因为TIME_WAIT大量产生很多都发生在实际应用环境中. TIME_WAIT产生的原因还是因为在通讯过程中服务端主动关闭

《软件调试的艺术》笔记--调试多线程程序

下面是于线程相关的GDB命令用法汇总: info threads:给出关于当前所有线程的信息. thread 3:改成线程3. break 88 thread 3 :当线程到达源代码88时停止执行. break 88 thread 3 if i == 2 当线程3到达源代码行88行,并且变量i的值为2时停止执行. 对下面的多线程进行调试: #include <stdio.h> #include <pthread.h> #include <string.h> #inclu

学习笔记_springmvc文件上传和拦截器

文件上传 用到这两个包 配置视图解析器:springmvc配置文件配置 <!-- id必须要是"multipartResolver" --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- maxUploadSize文件上传的最大值,单位是byte