• .net-----多线程编程技术


    前言

    线程与创建多线程

    线程状态和生命周期

    线程同步和通信

    线程池

    定时器

    并行处理和异步处理

    线程与创建多线程

    进程

    • 操作系统中正在执行的不同应用程序的一个实例

    线程

    • 操作系统分配处理器时间的基本单元

    • 维护异常处理程序、调度优先级和一组系统用于在调度该线程

    • 前保存线程上下文的结构

    • 操作系统和处理器

    • 线程处理使程序能够执行并发处理,因而特别适合需要同时执行多个操作的场合

    • 多线程处理可解决用户响应性能和多任务的问题,但同时引入了资源共享和同步问题等问题,占用资源和处理器调度实际大,影响运行性能

    创建多线程应用程序

    • 应用程序运行时,创建新的应用程序域
    • 运行环境调用应用程序的入口点(Main方法)时,将创建应用程序主线程
    static void Main()
        {
            Console.WriteLine("主线程:开始……");
            Thread.Sleep(5000); // 主线程睡眠5秒钟
            Console.WriteLine("主线程:结束!");
            Console.ReadKey();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • System.Threading命名空间提供支持多线程编程的类和接口

    • 创建新线程:

    • 创建一个将在主线程外执行的函数,即类的方法,用于执行新线程要执行的逻辑操作

    • 在主线程(Main方法)中创建一个Thread的实例,指向步骤1中的函数
      Thread newThread = new Thread(anObject.AMethod)

    • 调用步骤2中创建的Thread的实例的Start()方法,以启动新线程
      newThread.Start()

     static void Main()
            {
                Console.Write("Main线程开始。"); 
                Thread t = new Thread(DoWork); //创建线程对象实例
                t.Start(); //启动工作线程
                for (int i = 0; i < 10; i++) { Console.Write("M"); Thread.Sleep(500); }
                Console.Write(" Main线程结束。"); Console.ReadKey();
            }
            public static void DoWork()
            {
                Console.Write("工作线程开始。");
                for (int i = 0; i < 10; i++) { Console.Write("W"); Thread.Sleep(500);}
                Console.Write(" 工作线程结束。");
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    线程状态和生命周期

    线程的生命周期的执行状态

    Unstarted, Running, Suspended, Aborted, Stopped, ……

    • 通过执行相应的操作,线程可以转换为对应的状态

    • 创建新线程→Unstarted

    • 线程响应Suspend请求→ Suspended

    • 另一个线程调用Abort → AbortRequested

    • 线程被终止→ Stopped

    • 通过Thread对象实例的方法

    • 设置或获取线程属性
      t.name, t.Priority, t.IsBackground…

    • 操作线程
      t.Start() →启动
      t.Abort() →停止
      t.Suspend() →挂起
      t.Resume() →继续线程

    • 休眠(暂停)
      静态方法Thread.Sleep()和Thread.Sleep()强制当前正在执行的线程休眠

    • 线程让步
      Thread.Yield()

    • 线程加入
      t.Join(),让包含代码的线程(即当前线程)“加入”到另外一个线程的尾部

    • 线程中断
      Interrupt(),以在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态

    • 线程终止/销毁
      Abort(),永久地停止托管线程

    • 前台线程和后台线程

    • 前台线程是通常意义的线程,从主线程进入,主线程中可以创建新的用户线程

    • 后台线程是一个服务线程,具有最低的优先级
      通过设置线程的IsBackground属性为true来设置后台线程

    线程同步和通信

    • 线程优先级和线程调度

    • 在运行库内创建的线程最初被分配 Normal 优先级,通过线程的Priority属性可以获取和设置其优先级

    • 线程同步处理

    • 当多个线程可以调用单个对象的属性和方法

    • 一个线程可能会中断另一个线程正在执行的任务,使该对象处于一种无效状态

      • lock语句同步代码块,监视器同步代码块

    使用lock语句同步代码块

    • lock关键字可以确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区

    • lock语句以关键字lock开头,并以一个对象作为参数,在该参数的后面为线程互斥的代码块

    private Object thisLock = new Object();
    lock (thisLock)
    {
        ……
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用其他方法同步代码块

    使用监视器(Monitor)
    调用Monitor.Enter方法,允许一个且仅一个线程继续执行后面的语句;其他所有线程都将被阻止,直到执行语句的线程调用Exit

    使用MethodImplAttribute特性实现方法同步处理

    使用SynchronizationAttribute特性实现类同步处理

    同步事件和等待句柄

    • 同步事件允许线程通过发信号互相通信,从而实现线程需要独占访问的资源的同步处理控制

    • 同步事件有两种:
      AutoResetEvent(自动重置的本地事件)
      ManualResetEvent(手动重置的本地事件)

    • 每种事件的两种状态:
      收到信号状态(signaled)
      未收到信号状态(unsignaled)

    使用Mutex同步代码块

    • 与监视器类似,用于防止多个线程在某一时间同时执行某个代码块
    • 与监视器不同的是,mutex 可以用来使跨进程的线程同步

    线程池

    • 可以用来在后台执行多个任务的线程集合,这使主线程可以自由地异步执行其他任务

    • 异步处理可不占用主线程,也不会延迟后续请求的处理

    • 通常用于服务器应用程序

    • 可使用ThreadPool类创建线程池

    定时器

    • System.Threading.Timer是一种定时器工具,用来在一个后台线程计划执行指定任务

    • Timer提供以指定的时间间隔执行方法的机制

    • TimerCallback timerCB=new TimerCallback(PrintTime);

    • Timer timer1 = new Timer(timerCB,”timer1”,0,1000);

    并行处理和异步处理

    • 并行处理

    • 基于Task Parallel Library(TPL,任务并行库),可以使多个独立的任务同时运行

    • 隐式创建和运行任务

    • 使用Parellel的静态方法Invoke

    • 显式创建和运行任务

    • 命名空间System.Threading.Tasks的Task类和Task类

    • 异步处理

    • 无须等待方法执行完毕,在执行异步方法的同时,可继续执行其他处理

    • 通过委托实现异步方法调用

    • async和await关键字

  • 相关阅读:
    SBCS、DBCS、ASCII、MBCS(ANSI)、Unicode
    python在cmd中运行.exe文件时报错:不是内部或外部命令,也不是可运行的程序或批处理文件。的解决办法
    线性筛求欧拉函数前n个和
    悬崖边:企业如何应对网络安全漏洞趋势
    Appium混合页面点击方法tap的使用
    实习生跑路留了一个大坑,搞出2个线上问题,我被坑惨了
    2022年2000元能玩原神的手机推荐 这3款值得买
    vue3快速入门-生命周期
    如何正确选择ARM核心板的存储类型
    N32学习笔记2-GPIO使用和关闭JTAG打开SW调试模式
  • 原文地址:https://blog.csdn.net/weixin_51422230/article/details/128055883