线程基础
Posted *Hunter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程基础相关的知识,希望对你有一定的参考价值。
一、线程开销
线程有空间(内存耗用)和时间(运行时的执行性能)上的开销
①线程内核对象
OS为系统中创建的每个线程都分配并初始化这种数据结构之一(对线程进行描述的属性、线程上下文)。上下文是包含CPU寄存器集合的内存块。对于x86,x64和ARM CPU架构,线程上下文分别使用约700,1240,和350字节的内存
②线程环境块(TEB)
TEB是用户模式(应用程序代码能快速访问的地址空间)中分配和初始化的内存块。TEB耗用1个内存页(x86,x64和ARM CPU中时4kb)。TEB包含线程的异常处理链首(head)。线程进入每个try块都在链首插入一个节点;线程退出try块时从链中删除该节点。此外,TEB还包含线程的"线程本地存储"数据,以及由GDI和OpenGL图形使用的一些数据结构
③用户模式栈
用户模式栈存储传给方法的局部变量和实参。还包含一个地址;指出当前方法返回时,线程应该从什么地方接着执行。Windows默认为每个线程的用户模式栈分配1MB内存。更具体的说Windows只是保留1MB地址空间,在线程实际需要时才会提交(调拨)物理内存
④内核模式栈
应用程序代码操作系统中的内核模式函数传递实参时,还会使用到内核模式栈。出于对安全的考虑,针对从用户模式的代码传给内核的任何实参,Windows都会把它们从线程的用户模式栈复制到线程的内核模式栈。OS内核代码开始处理复制的值。除此之外,内核会调用它自己内部的方法,并利用内核模式栈传递它自己的实参、存储函数和局部变量以及存储返回地址。在32位Windwos上运行,内核模式栈大小是12kb;64位是24kb
⑤DLL线程连接(attach)和线程分离(detach)通知
Windows的一个策略是,任何时候在进程中创建线程,都会调用进程中加载的所有非托管DLL的DllMain方法,并向该方法传递DLL_THRAND_ATTACH标志。类似的,任何时候线程终止,都会调用进程中的所有非托管DLL的DllMain方法,并向方法传递DLL_THRAND_DETACH标志。有的DLL需要获取这些通知,才能为进程创建/销毁的每个线程执行特殊的初始化或(资源)清理操作。VS在它的进程地址空间加载了大约470个dll!这意味着每次在VS中创建或者销毁一个线程,都必须先调用470个dll函数
Windows任何时刻只将一个线程分配给一个CUP。那个线程能运行一个“时间片”(有时也称为“量”或者“量程”)的长度。时间片到期,Windows就上下文切换到另一个线程
二、使用专用线程
应尽量使用线程池来执行异步的计算限制操作。如果满足一下任何条件则可以使用专用线程
①线程需要以非普通线程优先级运行。所有线程池都以普通优先级运行
②需要线程表现为一个前台线程,防止应用程序在线程结束前终止。线程池始终是后台线程
③计算限制的任务需要长时间运行
④要启动线程,并可能调用Thread的Abort方法来提前终止它
static void Main(string[] args) { //创建专用线程 Thread th = new Thread(ComputeBoundOp); th.Start(5); th.Join();//等待线程终止 Console.ReadLine(); } private static void ComputeBoundOp(Object state) { //这个方法由一个专用线程执行 Console.WriteLine(state); Thread.Sleep(1000);//模拟做其他任务(1秒) //这个方法返回后,专用线程将终止 }
三、线程调度和优先级
只要存在可调度的优先级31的线程,系统就永远不会讲优先级0~30的任何线程分配给CPU。这种情况称为饥饿
较高优先级总是抢占较低优先级的线程
|
进程优先级类 |
Idle |
Below Normal |
Normal |
Above Normal |
High |
Realtime |
相对线程优先级 |
|
|
|
|
|
|
|
Time-Critical |
|
15 |
15 |
15 |
15 |
15 |
31 |
Highest |
|
6 |
8 |
10 |
12 |
15 |
26 |
Above Normal |
|
5 |
7 |
9 |
11 |
14 |
25 |
Normal |
|
4 |
6 |
8 |
10 |
13 |
24 |
Below Normal |
|
3 |
5 |
7 |
9 |
12 |
23 |
Lowest |
|
2 |
4 |
6 |
8 |
11 |
22 |
Idle |
|
1 |
1 |
1 |
1 |
1 |
16 |
大多数进程时Normal线程时Normal。所以大多数线程的优先级是8
//更改线程的相对线程优先级 th.Priority=ThreadPriority.Normal;
以上是关于线程基础的主要内容,如果未能解决你的问题,请参考以下文章
newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段