当前位置:编程学习 > asp >>

CLR线程总结

一、引言 

       一个应用软件一般对耗时或需要异步执行的操作开辟单独的线程执行,使用多线程有助于提升软件系统的健壮性和可响应性,使得用户体验得到大的提升。本文主要谈在.NET平台中CLR线程基础技术以及在CLR中如何更优化地使用线程技术。


     二、CLR线程基础

      早期的Windows操作系统,整个系统只运行一个执行线程(当时操作系统没有提供线程概念),如果某个应用程序长时间运行或者陷入死循环,其他程序只能干巴巴地等待,很容易造成整个系统停止工作,只能绝望地重启电脑,更让人疯狂的是,这种情况会造成正在处理的数据无端丢失。后来微软对操作系统内核进行了大量改进,提出了进程(Process)和线程(Thread)的概念。


      进程就是一个可执行的程序一次运行的过程,它是系统进行资源分配和调度的一个独立单位。直观地说,你开启了一个应用程序,就启动一个进程,这个进程被分配了保障应用程序顺利执行的各种资源,如内存,CPU,文件句柄,GDI资源等。系统内核为每个进程分配了独立的虚拟空间,这些地址空间只提供给一个应用程序实例使用,而且这个应用程序实例需要的所有资源都是在这个独立的虚拟空间获取,这样的好处是确保程序实例的健壮性,提升了系统安全性,因为虚拟空间独立也意味着程序实例独立,不用担心一个实例破坏另外一个实例的代码和数据,也不用担心一个程序实例的密码用户信息给另外实例读取。但这个时候一个程序死循环,其他程序只能死等的问题还在,因为如果只有一个CPU,那么CPU会被死循环的程序一直占有。为解决这个问题,微软提出线程概念。如果进程是对内存地址空间的虚拟独立,那么线程就是对CPU的虚拟独立,Windows内核为每个进程提供了该进程专用的线程(功能相当于一个CPU,称为逻辑CPU,实际上单CPU的计算机CPU一次只给一个进程使用,所以Windows必须实现逻辑CPU(线程)共享物理CPU,用的机制就是CPU的“时间片”管理,简单地说就是把一个单位时间内的CPU使用划分为很多个更小时间粒度的时间片,每个时间片的时间内CPU只给一个线程使用,Windows的CPU时间片大约是30毫秒),如果某个程序实例代码进入死循环,与之关联的进程冻结,但其他进程可以继续执行。这个时候,我们可以在“任务管理器”上强制终止冻结的应用程序。 
     
      创建一个线程,让这个线程进驻到系统到最后销毁这个线程会产生空间内存和执行时间的开销,如某个进程创建一个新的线程时会初始化线程内核对象,会调用这个进程加载的所有DLL的DllMain方法,终止这个线程又会调用这个进程加载的所有DLL的DllMain方法。现在一些大型软件的DLL动辄有数百个,在这样的软件进程中创建线程和销毁线程都会极大影响性能。一方面为了性能考虑,我们必须尽量少创建线程,另一方面,为了使得应用程序更强壮,反应更灵敏,必须使用多线程。CLR提供了一些机制,可以在保持代码响应能力的同时尽量少创建线程,比如线程池技术。

     在CLR中创建一个专用线程非常简单,我们有时候需要软件的时候把一些软件用到的基础数据加载到内存中,我们用新的线程来模拟这一过程:

namespace CLRThread
{
    class Program
    {
        static void Main(string[] args)
        {

            Thread thread = new Thread(n=>LoadBaseData((int)n));
            thread.Start(4);
            Console.ReadLine();
        }

        /// <summary>
        /// 加载基础数据
        /// </summary>
        /// <param name="count"></param>
        private static void LoadBaseData(int count)
        {
            for (; count > 0;count-- )
            {
                Thread.Sleep(1000);//模拟加载基础数据工作
                Console.WriteLine("加载完基础数据 {0}  ", count);
            }
        }
    }
}

     这里使用了System.Threading.Thread类的常用的构造器public Thread(ParamterizedThreadStart start)来创建Thread的实例,参数start就是线程要执行的方法,这个方法要和委托 delegate void ParamerizedThreadStart(Object obj);的签名匹配。


     实例一个Thread对象,并没有在系统中创建一个线程,只有在调用Start方法后才真正创建一个系统线程。下面展示了Thread的一些常用成员。

 

属性 作用
CurrentThread 静态属性,获取当前正在运行的线程
IsBackground 获取或设置一个值,该值指示是否是后台线程
Name 获取或设置线
补充:Web开发 , ASP.Net ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,