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类库,作者写的....

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

  • 相关阅读:
    257. Binary Tree Paths
    324. Wiggle Sort II
    315. Count of Smaller Numbers After Self
    350. Intersection of Two Arrays II
    295. Find Median from Data Stream
    289. Game of Life
    287. Find the Duplicate Number
    279. Perfect Squares
    384. Shuffle an Array
    E
  • 原文地址:https://www.cnblogs.com/dacude/p/4382616.html
Copyright © 2011-2022 走看看