zoukankan      html  css  js  c++  java
  • 25线程基础-CLR

    由CLR via C#(第三版) ,摘抄记录...

    1、线程是CPU的虚拟化,windows为每个进程提供专用线程(CPU)
    2、线程开销:内存和时间。
    线程内核对象—OS为系统中创建的每个线程都分配并初始化这种数据结构之一。其中包含对线程进行描述的属性,和上下文。上下文是内存块,x86的是约700字节,x64是约1240,ia64是2500。
    线程环境块TEB,用户模式中的内存块(应用程序代码能快速访问的空间),一个TEB一个内存页,x86和x64都是4KB,IA64是8KB。 TEB包含线程的异常处理链首(head)。进入每一个try都在后面插入一个节点,退出try时删除该节点。 TEB还包含线程的本地存储 数据,以及GDI和OpenGL图形使用的数据。
    用户模式栈 存储传递给方法的局部变量和实参,还包含一个地址,指出方法返回时,线程从何处执行。默认1MB。
    内核模式栈 32位windows下为12KB,64的是24KB。
    DLL线程连接和线程分离通知 windows策略决定。。C#和其他托管语言的DLL没有DLLMain函数,不收通知,这提升性能。

    3、windows只将一个线程分配给一个CPU,允许其运行一个 时间片 ,上下文切换。
    切换:将cpu寄存器的值保存内核对象内部的上下文结构中,选出一个新线程供调度,将其内的上下文结构值加载到CPU。
    大约每30毫秒执行一次切换。净开销。而且还会切换高速缓存cache。尽可能避免切换。
    时间片结束时,如果windows决定再调度同一线程,就没有切换。这显著改进性能

    4、垃圾回收时,CLR暂停所有线程,遍历他们的栈进行标记,再遍历栈,再恢复所有线程。所以,减少线程数量会显著提升垃圾回收器的性能。调试时也挂起,线程越多,调试体验越差
    单个线程不会在多个内核CPU上调度,应在确保响应能力的同时创建尽量少的线程。理性使用线程。

    5、超线程CPU,芯片中包含2组架构状态,只有一组在执行,对于windows,看起来像是2个CPU,所有windows会同时调度2个线程。芯片一次只能执行一个。

    6、NUMA架构机器,(略)

    7、CLR线程和windows线程: CLR使用的是windows的线程处理能力。一个CLR线程直接对应一个windows线程。

    8、使用专用线程执行异步的计算限制操作。

      建议避免采用,应尽量使用CLR的线程池来执行异步计算限制操作。

      显示创建自己线程的条件:

        优先级高,不建议更改线程池的优先级;

        表现为一个前台线程,防止应用程序在线程结束它的任务之前终止。线程池中的是后台线程。

        一个计算限制的任务需要长时间运行。

        要调用Abort方法提前终止它。

      Thread.Join()等待线程终结

    9、使用线程的理由     代码隔离健壮性,简化编码,并发。

      观点改变,CPU计算能力富余,应大胆消费。

    10、线程调度和优先级  

       抢占式操作系统,使用算法判断在什么时间调度哪些线程多少时间。

      一个时间片后,windows检查现有所有线程内核对象,有资源的适合调度。从spy++可以查看切换的次数。线程在任何时间可以被抢占,windows调度另一个。你不能阻止其他线程的运行。

         所以,windows是抢占式操作系统,不是实时操作系统,CLR使托管代码的行为更不实时。比如:DLL的JIT加载,代码的JIT编译,GC无法预测的介入。

           线程优先级从0(最低)-31(最高),系统启动时有个为0的零页线程的特殊线程,唯一一个0的线程,在没有其他进程要调度时,将系统RAM所有空闲页清零。

      优先级类(priority class) :Idle,Below Normal,Normal,Above Normal,High和Realtime。 优先级类是用于进程的。每个线程的优先级取决于 他所属的进程的优先级类和在该进程内他自身的优先级——俩者合成基础优先级——动态优先级是OS确保线程可响应,不一直饥饿所产生。但是16-31之间的线程,系统不提升他们的优先级。0-15的才提升。

      应用开发人员永远不直接处理优先级。Normal的Normal是8,大多数程序都是8的优先级。Windwos永远不会调度进程,只调度线程。进程根据启动它的进程来分配一个优先级。大多数进程都是windows资源管理器启动的,属于Normal。

      托管应用程序不应该表现为拥有自己的进程;相反,他们应该表现为在一个AppDomain中运行。 可以更改他的线程相对优先级,设置Thread的Priority属性。System.Diagnostics命名空间包含一个Process类和ProcessThread类,提供进程和线程的windows视图。AppDomain和Thread类,公开了应用域和线程的CLR视图。

    11、 前台线程和后台线程

       线程在CLR中要么是前台,要么是后台。一个进程中的所有前台停止时,CLR强制终止扔在运行的任何后台线程。--直接终止,不抛出异常。

      

     1     public static void Main()
     2         {
     3             //  创建一个新线程(默认为前台线程)
     4             Thread t = new Thread(Worker);
     5 
     6             Console.WriteLine(t.IsBackground.ToString());
     7             //  使线程成为一个后台线程
     8             t.IsBackground = true;
     9             t.Start(); //  启动线程
    10             //  如果 t 是一个前台线程,则应用程序大约 10 秒后才终止
    11             //  如果 t 是一个后台线程,则应用程序立即终止
    12             Console.WriteLine("Returning from Main");
    13             Console.Read();
    14 
    15         }
    16         private static void Worker()
    17         {
    18             Thread.Sleep(10000); //  模拟做 10 秒钟的工作
    19             //  下面这一行代码,只有在由一个前台线程执行时,才会显示出来
    20             Console.WriteLine("Returning from Worker");
    21 
    22             Console.Read();
    23         }
    24     }
    后台线程

      在线程生存期内,随时可前后变换。应用的主线程以及通过Thread对象显示创建的都默认前台,线程池默认后台。由进入托管执行环境的本地代码创建的线程被标记为后台。应尽量避免使用前台线程

       wintellect类库,作者写的....

    ~~~~~~~~~~待续~~

  • 相关阅读:
    fis3解决web网站缓存问题
    C# 计算每周和每月固定日期
    移动端web页面上滑加载更多功能
    常见三种字符编码的区别:ASCII、Unicode、UTF-8
    ef AddDays报错
    .NET语言的编译过程:中间语言(IL)和即时编译器(JIT)
    ajax 传递数组类型参数后台接收不到的问题
    sql server 作业没跑、开启sql 代理服务、新建作业
    在javascript中NodeList和Array的区别及转换方法
    我经历的几种开发模式和心理
  • 原文地址:https://www.cnblogs.com/dacude/p/4382616.html
Copyright © 2011-2022 走看看