《CLR via C#》读书笔记-.NET多线程(一)

来源:互联网 发布:氮素网络是什么意思 编辑:程序博客网 时间:2024/04/30 08:37

1、进程(Process)
进程是应用程序的一个实例要使用的资源的集合。每个进程都会分配一个虚拟地址,确保另一个进程的代码和数据不会被访问。
2、线程(Thread)
线程可以理解一个逻辑CPU
线程基本信息
线程包含:线程内核对象、线程环境块、用户模式栈、内核模式栈、DLL线程连接和线程分离通知
1、线程内核对象。是一种数据结构。是线程的最基本信息,包含线程属性信息、线程上下文(thread context)。其中上下文是一个内存块,其包含了CPU的寄存器集合。(寄存器,一种用于暂存程序中间结果的快速内存)。
线程上下文会占用内存空间。在x86机器上,会占用700byte左右(约为0.7K),若在X64上,占用1K左右
2、线程环境块(thread environment block,TEB)。
在用户模式下才会分配和初始化的一个内存块。其包含了线程的异常处理链首(即,线程的try catch块信息,线程在进入try块时,需要向在异常处理链首(即某种栈)push,在推出try后,会pop出异常处理链首);线程的本地存储数据;GDI和OpenGL图形使用的一些数据结构(个人感觉,这部分一般都不会读取或写入,系统会自动进行相应的处理)。在x86和x64中占用4K大小左右
3、用户模式栈。这是一个栈,用于存储线程用到的局部变量和实参。以及栈弹出时的地址数据。系统初始化时,会默认分配大约1M左右的空间,进行存储相关数据
4、内核模式栈。当多线程并发竞争时,.NET会有两个方式,用户模式和内核模式,解决线程之争。当使用内容模式时,代表.NET将调用window内核相关的方法处理多线程并发的之争。而window内核的数据是不能被.NET直接访问的,因此.NET需要将用户模式栈的数据全部存储到内核模式栈中。同时,window内核在调用内核的相关方法时,也会把相关的参数、指针等信息存储在内核模式栈。因此内核模式栈的本质就是为了保证window内核直接读取.NET线程的数据而采取的这种的一种方式。在win32上,其大小为12KB,win64上,其大小大约为24KB。
有一个有趣的地方,用户模式栈大约会用到1M,而内核模式栈中最大为24KB,是用户模式的1/5,看出来,.NET还是很“浪费”的。
5、DLL线程链接和线程分离通知。创建进程时,可能会调用其他的DLL,在创建线程时,window会调用在进程中加载的DLL的DllMain方法,并传入(DLL_THREAD_ATTACH)标志,看看其他的DLL中有没有需要做事情的;若线程结束,则再通知涉及到的DLL的DllMain方法,并传入(DLL_THREAD_DETACH)。不过当前托管程序生成的DLL中没了DllMain方法,因此也就不用去调用了,提高了性能。若为非托管程序,可通过Win32的DisableThreadLibraryCalls来决定是否理会这些通知。在托管程序中本部分不占用空间。
因此一个在win64的线程大约占用的空间为:1K+4K+1M+24K=1053KB,即1M多点。也可以默认为1个线程1M内存占用。
因此程序中创建过多的线程会占用很多的内存。
上下文切换
但除了系统会占用的内存,CPU会在使用多线程时,进行不同线程之间的切换。
过程如下:
1、将正在执行的线程的相关实参等数据压入该线程的上下文中
2、选取即将执行的线程
3、将即将执行线程的上下文的数据弹出,并存入至CPU的寄存器中
目前window的上下文大约在30毫秒执行一次上下文切换。当然,若同一线程的到了上下文的时间,且将要执行的还是当前线程,则系统不会进行上下文的切换。另外,线程还有一种提前终止其时间片的功能,不需要30毫秒完成的事情,做完后会CPU会提前进行上线文的切换。最后,在垃圾回收时,CPU会暂停所有的线程,并根据栈进行查找每个对象的根,并标记对象,然后不用的对象就会被删除。
window定时的执行不同的线程,有点类似于通信原理中TD-XX的意思,即时分-XX的感觉。
因此,从占用空间角度、上下文切换角度、垃圾回收器的角度而言,都要尽量不要创建线程。但若是程序需要,该创建还得创建
PS.用户模式栈中占用的1M空间,当程序为本地代码(即非托管程序)时,其不是立刻占用,而只是保留地址空间,并没有实际分配空间;但若时托管程序,则是一定会分配1M空间
CPU发展
1、多个CPU。主板上实打实的CPU
2、超线程芯片。这是Intel的专利。从硬件上实现,一个CPU采用“时分”方式处理。因此对window而言,它认为有两个CPU
3、多核芯片。
说一下多个CPU与多核芯片的区别。多核芯片就是多个CPU共用一套存储、高速缓存等,而多个CPU就是实打实的多个CPU,有各自的高速缓存等。详细的情况可参见知乎:知乎关于多核CPU和多CPU的回答
NUMA架构
《CLR via C#》中有一节专门讲了NUMA架构,但是个人认为.NET在近期不会考虑NUMA架构上的.NET事宜。
理由有二:微软整体的战略转向win10、UWP等方向,对于没有多大市场的NUMA市场,这方面的事情应该排在靠后的位置
理由二:NUMA有多大?研发投入比比较低,从收益上,微软也会把它排后面吧
补充,一般至64的CPU是指每次询址为64位,而64位的操作系统可以认为是操作系统最多支持64个CPU核。

0 0
原创粉丝点击