首页 / 网页编程 / ASP.NET / 浅谈.NET下的多线程和并行计算(十二)CLR via C#第三版阅读笔记(1)
        
            浅谈.NET下的多线程和并行计算(十二)CLR via C#第三版阅读笔记(1)2011-08-03 博客园 lovecindywang最近此书出了第三版,在阅读此书线程部分的过程中有很多心得,补充了此前知识盲点,因此把这些 关键和重要的知识点汇集成日志文章并且纳入到这个系列中。顺便说一下,笔者喜欢这本书的原因是作者 作为微软顾问并没有按照MSDN的教条教大家怎么去用而是能说出很多自己的观点甚至很多是微软.NET框架 不够的地方,并给出自己的实现。为什么说线程是比较昂贵的?1)从内存上来说,(对于32位架构)每一个线程包含线程内核对象(700字节)/线程环境块(4KB)/ 内核堆栈(12KB)/用户堆栈(1MB)。并且可以发现,这1MB的用户堆栈内存在CLR线程创建的时候完全分 配,并不是动态增加的(Windows线程的创建只是保留1MB的内存空间)。2) 从线程切换上来说,需要做哪些步骤来进行切换?首先是把CPU寄存器中的值保存到当前线程的内 核对象中,然后如果线程切换到不同CPU的话需要为CPU准备新的虚拟地址空间,最后把目标线程内核对象 中寄存器的值复制到CPU寄存器中。3) 更大的性能损害来自于,线程切换之后缓存中的数据可能会不能命中,需要重新准备这些数据。4) 此外,在垃圾回收的时候,CLR会挂起所有线程,查看线程堆栈,垃圾回收压缩后重置堆栈指针地 址。当然,线程总比进程的创建好一点,不过作者也说了线程多啊,一个OUTLOOK有几十个线程,作者还纳 闷怎么打开记事本的打开对话框会多22个线程,我想这个和操作系统有关,Vista的打开文件对话框更复 杂,在其中为了不阻塞UI很多Part都以新的线程来加载内容,还好这个打开对话框用的不是 CLR线程…… 当前CLR线程对应Windows线程,作者也希望在将来CLR能实现虚拟逻辑线程的概念,以改善性能。什么时候手动创建线程而不是使用线程池?1) 需要自定义线程的优先级,线程池的线程总是Normal。2) 需要一个前台线程,线程池的线程总是后台线程。作者建议大家对于非UI线程创建为后台线程而不是前台线程,有的时候我们可以发现有些软件在关闭 之后,或者说关闭UI之后在进程中还存在,占用内存,这是因为我们看到关闭的是UI线程,还有其它前台 线程未关闭。3) 需要手动中止线程,线程池不提供这个功能。4) 线程执行时间很长,线程池用于短而多的线程任务比较合适。线程的调度1) 每一个线程的优先级是0到31。高优先级的线程ready之后,不管低优先级的线程在做什么,立即 上位,没话说。Windows会把最高优先级的不同线程调度到各个CPU上并行执行,多核多处理器谁也不闲着 。2) Windows制定进程有6个优先等级,线程有7个,通过组合来得出实际的线程优先级0到30(0优先级 保留给Windows用于内存释放)。CLR保留了线程优先级中的最低和最高级,供程序员可设置的只有5个等 级。3)进程的优先级是一个虚拟的概念,只是为了帮助用于映射到1-31中的某个等级,一般来说进程的等 级默认为创建它的进程的等级。很多进程都是Windows Explorer创建的,默认也就是Nomral这个等级,说 白了我们的线程在大多情况下映射到Windows线程优先级为6-10。