线程基础

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()自定义线程池(代码片段

JavaSE线程基础

Java——线程池

Java线程池详解

Java线程池详解

Java 线程池详解