多线程技术
多线程技术
目录
正文内容:
一、计算机线程
1、计算机的线程如图:
2、计算机中的线程: 任务管理器中事四核八线程(逻辑处理器),意味着能同时执行8个任务。任务管理器中有1472个线程,但是绝大部分都在休眠,但不管怎么休眠,线程数还是远远超过8个(实际线程数)
3、进程:运行一个程序就会有一个进程,一个进程又会有很多个线程
4、CPU资源分配方法:资源分配其实是按照线程分配(分配过程忽略),计算机及执行的时候,也会考虑到进程的优先级问题,计算机执行的时候,也会考虑到优先级问题,优先级受操作系统控制,一般不收开发者控制,因为如果开发者能随意更改优先级,将会产生很多流氓软件
5、当实际线程数多于CPU逻辑处理器时,时如何执行这些线程的呢?引入时间片的概念。采用时分复用技术,码分多址技术和频分多址技术等。时分复用技术,以1秒为单位,1时间片大概30毫秒,就等于1秒约等于33片,假如有9个线程,分别以几个时间片的单位执行,执行完时间片切换到下一个线程,如图线程和占用时间片(33个时间片9个线程),每个线程分配的时间片不同,
1111 | 1111 | 11111 | 1111 | 11111 | 111 | 111 | 11 | 111 | ..... |
线程1 | 线程2 | 线程3 | 线程4 | 线程5 | 线程6 | 线程7 | 线程8 | 线程9 | 其他线程 |
线程是以串行执行,切换速度很快
6、多线 程技术使得程序的并行执行(从微观上实际是并发)成为可能。例如,一个线程播放音乐,另一个线程下载文件,它们可以“同时”使用CPU和内存等资源,彼此却没有因此而受到影响(从用户角度看)
二、怎么看待线程开销问题
1、我们通常写的程序都是同步的,如果我们想主动增加线程,就必须独立开启
2、开启一个线程,时间上和空间上都需要开销
3、开发中我们不能过多的开启线程,否者性能不仅不会提高反而会下降
三、多线程实现形式
1、异步编程:
- 最早在.NET 1.0时代,可以基于异步编程,就是可以同时多个任务(并行执行)
- 异步编程是基于委托实现的,现在用的很少
- 其主要核心是invoke方法和回调函数
- 因为功能弱,编写麻烦,有其他简单的可供选择,所以用的很少
2、Thread线程:简化了异步编程编写方法,但因为时间和空间的开销较大,并且垃圾回收机制GC也不是很快捷,同样使用的少。thread方式 需要一个就得我们自己 new一个
3、ThreadPool线程池:顾名思义,提前准备好,想用就拿过来用,用完放回去就行
4、需求如表:有A B C D E五个线程
A-->B-->C-->D-->E | 顺序执行 |
(A,B,C,D)-->E | ABCD全部执行完后再执行E |
(A,B,C,D)-->E | ABCD中任意一个完成就执行E |
A-->B-->C(error)-->D-->E | 当C发现错误,可以取消整个任务链 |
。。。。。。。。。。 | 。。。。。。。。。。。。。 |
5、Task: Thread和ThreadPool虽然可以使用,有的 7ff7 时候还很不错,但是功能不能满足我们的需求,所以出现了Task,Task可以说是Thread和ThreadPool的结合,但不是简单结合,在性能上,资源开销上,都得到很好的优化,在.NET4.0以后,不管大小微软都建议使用Task
6、其他的并行编程,如parallel等。。。。
四、多线程的代码分析阶段
1、为了搞懂原理,建议使用windbg,windbg是一个能够观察程序底层的工具,尤其是线程等
2、windbg的使用(本机路径):
使用步骤:
- 首先找到clr.dll和sos.dll,VS安装目录——》Windows——》Microsoft.NET——》framework64——》V 4.0 30319——clr.dll和sos.dll
- 然后将clr.dll和sos.dll复制到windbg安装目录中,启动windbg.exe并配置windbg工具,附加一个进程,加载.clr.dll和sos.dll后(.loadby clr sos)完成剩下操作,注意要运行的是debug中的要测试线程的.exe文件才行
windbg看看的内容:
- windbg命令:.loadby clr sos——加载clr和sos模块;!threads——查看所有线程;!ThreadState 线程号——查看线程状态
- 线程终结器(MTA(Finalizer)):主要作用就是回收线程,起作用跟回收站类似,线程不用先到线程终结器中,还可以回复,不想恢复的话最后会被GC清理
- 系统线程:主线程
3、前台线程和后台线程的区别:
- 前台线程:如果一个程序有前台线程,必须在所有前台进程都结束后才能推出程序
- 后台线程:如果一个程序开启的都是后台线程,那么在退出程序后,后台线程也就会全部退出
4、应用程序域:
- 一个应用程序对应一个进程,每个进程都会映射物理内存,从而隔离程序,进程是隔离的
- 问题引入:计算机在执行不同进程的同时,会跨进程,耗费时间
- 需求:希望一个进程中能使用另一个程序,但又不想单独用进程启动,因为进程开销大,根据问题和需求.NET引入应用程序域(appDomain)的概念,并且将它设置在进程和线程之间
- 每一个进程至少会包括一个应用程序域。在托管代码运行时,CLR还会额外创建系统域和共享域存放所有应用程序都需要的资料
5、线程的声明周期:thread生命周期中各个实例方法,开始、暂停、继续、中断和重新开始;和thread相关的静态方法,数据槽、本地数据 存储等
五、线程在内存空间上的开销
1、Thread内核数据结构:
- 主要有OSID(线程的ID)和contex上下文(存放CPU寄存器相关的变量)
- 理解:CPU切换任务时,会保存相关数据以备下次使用,(寄存器就是主要的存储)
2、查看当前环境块(!teb):(Thread Environment Block)线程环境块,下图参数就是内存的开销,都会占用资源,所以要研究
3、用户模式堆栈:
- 用户程序的“局部变量”和“参数传递”所使用的堆栈
- 常见的某些循环中出现溢出StackOverFlowException,一般都是死循环,一个线程分配1MB的堆栈空间,主要是参数、局部变量
4、内核模式堆栈:程序最后,还得调用底层的Win32函数,用户模式的参数必须还得传递过来,这部分肯定还会占用空间
六、线程在时间上的开销
1、资源使用通知开销:从Modeload列表中,就能看出资源加载必须要通知的
用!dumpdomain查看 应用程序域,有三部分系统域(system domain)、共享域(shared domain)和私有域(domain1,应用程序自己的)
2、时间片切换开销:切换线程开销也很大
七、线程池
1、Thread:也就是一个任务,开启一个thread需要时间,并且threaddied的时候,在一定时间内也会 占用资源
2、threadPool线程池:由系统完成并缓存,默认都已经初始化完毕,并且没有死线程。可以随时拿来用,用完随时放回去
发现:没有死线程,并且线程数只有4个,因为有4个逻辑处理单元,理论开启4个线程。也可以设置线程个数,不建议自己设置
3、thread和threadpool总结:当我们使用thread的时候,创建10个线程,就会有10个独立的线程运行,浪费时间和空间。但是,当我们使用threadpool的时候,解决10个独立线程能完成的任务。随着CPU核心的增加,这个线程池的个数也会增加,性能也会增加。独立线程个数减少,开销也会减少
4、虽然threadpool可以使用,但是满足不了一些特俗要求,所以有了Task,Task是threadpool和thread结合后功能的进一步增强
异步开启方式:
Task.start()方法
Task.Run()方法
Task.Factory.StartNew()方法
同步开启方式
- VC中利用多线程技术实现线程之间的通信
- VC中利用多线程技术实现线程之间的通信
- Java多线程技术中所有方法详解
- 通过WCF服务,采用多线程技术上传大文件到SharePoint文档库解决方案(初稿)
- .NET多线程技术详解(1)
- 在WPF程序中使用多线程技术
- 周六给公司做了个delphi技术培训,主要是中间层技术及多线程技术(2010-11-06)
- Java 多线程技术探究
- 运用多线程技术实现文件的快速搜索
- java多线程技术
- 基于WIN32 API及MFC的多线程技术
- Java多线程技术初识——5. 死锁
- 跟着BOY 学习COCOS2D-X 网络篇---强联网(采用技术 BSD SOCKET+多线程技术 +protobuf)(环境搭建篇+服务器)
- 利用多线程技术实现线程之间的通信(转)
- VC中利用多线程技术实现线程之间的通信
- java多线程技术一
- OS X 和 iOS 中的多线程技术
- iOS多线程技术的深度探究二: NSThread多线程技术
- 多线程技术中GCD与NSOperationQueue的区别
- iOS- 多线程技术的概述及优点