CLR线程和window线程
CLR线程完全等价于windows线程。System.Environment类公开了CurrentMangagedThreadID属性,返回的是线程的CLR ID。
而System.Diagnostics.ProcessThread类公开了Id属性,返回同一个线程的Windows ID。
主线程和子线程
当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序开始时就执行的,如果你需要再创建线程,那么创建的线程就是这个主线程的子线程,它是前台线程。
前台线程与后台线程
1、在CLR中,线程要么是前台线程,要么就是后台线程。当一个进程的所有前台线程停止运行时,CLR将强制终止仍在运行的任何后台线程,不会抛出异常。
2、在C#中可通过Thread
类中的IsBackground
属性来指定是否为后台线程。在线程生命周期中,任何时候都可从前台线程变为后台线程。线程池中的线程默认为后台线程。
3、在C#中,Thread类默认创建的是前台线程,通过线程池(后面会讲到)创建的线程都是后台线程。
4、前台线程与后台线程唯一的区别是后台线程不会阻止进程终止。
5、尽量避免使用前台线程。
线程优先级
Windows支持6个进程优先级类(priority class) :Idle,Below Normal,Above Normal,Hight(非必要不用)和Realtime(最好不要用)。默认的Normal是最常用的优先级类。
Windows支持7个相对线程优先级:Idle,Lowest,Below Normal,Normal,Above Normal,Highest和Time-Critical。
优先级类和优先级合并构成一个线程的“基础优先级”(base priority)。注意,每个线程都有一个动态优先级(dynamic priority)。线程调度器根据这个优先级来决定要执行哪个线程。最初线程的动态优先级和它的基础优先级是相同的。
线程优先级:windows 操作系统的线程优先级分为 0~31级。应用程序开发人员永远不直接处理这些优先级。只要使用相对优先级就够了。
系统将进程的优先级类和其中的一个线程的相对优先级映射成一个优先级(0~31)。下表总结了进程的优先级类和线程的相对优先级与优先级(0~31)的映射关系。
进程优先级类”和"相对线程优先级"如何映射到“优先级”值
|
进程优先级类 |
|
|
|
|
|
相对线程优先级 |
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。由于大多数进程都是Normal优先级,大多数线程也是Normal优先级,所以系统中大多数线程的优先级都是8。
注意,表中没有值为0的线程优先级。这是因为0优先级保留给零页线程了,系统启动时会创建一个特殊的零页线程(zero page thread)。该线程的优先级是0,而且是整个系统唯一优先级为0的线程。在没有其他线程需要“干活儿”的时候,零页线程将系统RAM的所有空闲页清零。系统不允许其他线程的优先级为0。而且,以下优先级也不可获得:17,18,19,20,21,27,28,29或者30。以内核模式运行的设备驱动程序才能获得这些优先级;用户模式的应用程序不能。还要注意,Realtime优先级类中的线程优先级不能低于16。类似地,非Realtime的优先级类中的线程优先级不能高于15。
而在C#程序中,可更改线程的相对优先级,需要设置Thread
的Priority
属性,可设置为ThreadPriority
枚举类型的五个值之一:Lowest、BelowNormal、Normal、AboveNormal 或 Highest
。CLR为自己保留了Idle
和Time-Critical
优先级,程序中不可设置。