当前位置: 首页 > article >正文

.net core修行之路-多线程异步编程概念篇

在 .NET Core 中,线程(Thread)的概念是非常重要的,特别是在涉及并发和多线程编程时。理解原生线程、托管线程、线程上下文、栈空间等概念,对开发高效的多线程应用至关重要。

下面我将详细讲解这些概念:

1. 线程(Thread)

线程是程序执行的基本单位,一个程序(进程)可以包含多个线程。线程共享同一个进程的资源,比如内存地址空间和文件句柄等。在 .NET Core 中,线程可以分为原生线程和托管线程,且它们有不同的生命周期、管理方式和执行模型。

2. 原生线程(Native Thread)

原生线程是由操作系统(OS)直接管理的线程,它与操作系统的调度和管理系统紧密相关。原生线程可以直接与操作系统交互,具有较高的灵活性。操作系统在调度原生线程时负责调度、切换和管理其状态。

在 .NET Core 中,原生线程是通过 System.Threading.Thread 类创建的。当你创建一个线程时,实际上你是在创建一个原生线程。

3. 托管线程(Managed Thread)

托管线程是由 .NET 的运行时(CLR,Common Language Runtime)管理的线程。CLR 负责管理托管线程的生命周期,包括调度、垃圾回收等。托管线程使用的是托管堆,CLR 会根据需要自动管理线程的内存分配、回收等。

  • 托管线程的优势

    • 自动内存管理:CLR 管理内存,垃圾回收机制会回收不再使用的对象和线程。
    • 更简化的 API:托管线程的创建和管理相对于原生线程更简化,例如使用 Task 或 async/await 模式来处理异步任务。
  • 与原生线程的关系:托管线程仍然依赖操作系统的原生线程进行实际执行。CLR 会通过线程池来管理这些线程,这样可以更高效地利用操作系统资源。

在 .NET Core 中,线程池中的线程通常是托管线程,通过 Task.RunThreadPool.QueueUserWorkItem 等 API 提供线程池的工作管理。

4. 线程池(Thread Pool)

线程池是一种多线程管理模式,在这种模式下,线程池会预先创建一定数量的线程,并在需要时从池中获取线程来执行任务,避免了频繁创建和销毁线程的开销。

  • 在 .NET Core 中,线程池使用了托管线程,通常用于执行短时任务和高并发的工作,避免了线程的过度创建和销毁。

你可以通过 ThreadPool 类来操作线程池,或者更常见的是通过 Task 类来使用线程池。

5. 线程上下文(Thread Context)

线程上下文指的是一个线程在执行时所依赖的环境信息,它包括线程的栈、寄存器值、调度信息、线程的状态等。

在 .NET Core 中,线程上下文包括但不限于以下几个方面:

  • 堆栈:线程有自己的栈空间,用于存储局部变量和调用信息。
  • 当前执行状态:线程当前在执行代码的上下文信息(例如:指令指针)。
  • 优先级:线程的优先级信息。
  • 安全上下文:例如 Windows 安全性、身份验证等,涉及线程在执行期间的权限和安全性。

在 .NET 中,线程上下文通常由 CLR 管理。如果线程执行的代码需要跨越不同的执行环境(比如从不同的线程池线程切换),CLR 会自动将相关的线程上下文(比如安全上下文、同步上下文等)传递给新线程。

6. 栈空间(Stack Space)

栈空间是每个线程都有的,它用于存储线程执行过程中的局部变量、方法调用的返回地址等信息。每个线程的栈是独立的,它用于执行线程的调用链。

  • 栈大小:每个线程的栈空间大小通常是固定的,默认情况下,栈的大小通常是 1MB,但可以在创建线程时调整栈的大小。

  • 线程栈的特点

    • 每个线程的栈是独立的,线程之间的栈不会互相影响。
    • 栈空间的大小有限,如果栈空间被耗尽(例如递归调用过深),会导致栈溢出错误(StackOverflowException)。

7. 多线程(Multithreading)

多线程编程指的是在同一进程内同时运行多个线程。每个线程都是独立的,执行不同的代码路径。在 .NET Core 中,利用多线程可以充分利用多核处理器,提高应用程序的响应能力和处理能力。

.NET Core 中的多线程编程可以通过以下几种方式实现:

  • System.Threading.Thread:创建原生线程,通过此类可以直接操作线程的生命周期。
  • Task 类:通过任务模型,使用 Task.Run 或 Task.Factory.StartNew 方法在后台线程中执行异步任务。Task 类是更高层次的抽象,通常更推荐用于多线程编程。
  • 线程池:通过 ThreadPool 类或 Task 类实现线程池任务,避免了手动管理线程创建和销毁的开销。

8. 异步编程与多线程的区别

虽然异步编程和多线程编程都涉及并发执行,但两者的实现和工作方式不同:

  • 多线程:通过创建多个线程并行处理多个任务,每个线程可以独立执行任务。线程之间可能需要共享资源,可能会引发同步问题。

  • 异步编程:主要是指在单个线程上执行多个任务,但通过非阻塞方式让任务在等待时释放控制权(例如 async/await)。异步操作通常会在 IO 等耗时操作时才使用,不会像多线程那样创建多个线程。

9. 线程的调度

.NET Core 的线程调度是基于操作系统的原生线程调度的。操作系统负责将线程分配到可用的 CPU 核心上运行。线程调度的目标是尽可能公平、高效地分配 CPU 时间,避免线程饥饿(某些线程永远得不到 CPU 时间)和竞争。

.NET Core 在不同平台(如 Windows、Linux)上会使用不同的线程调度策略,通常,操作系统的调度器会根据线程的优先级、CPU 使用情况和其它因素来决定调度策略。

总结

  • 原生线程:由操作系统管理,性能上灵活但创建销毁开销大。
  • 托管线程:由 CLR 管理,自动内存管理,适用于大多数高层次的应用。
  • 线程上下文和栈空间:线程的上下文包括其运行环境,栈空间则是存储线程执行过程中局部数据的地方。
  • 多线程编程:可通过 ThreadTask 和线程池实现。异步编程是另一种不涉及多线程的并发模型。

理解这些基本概念,有助于你在 .NET Core 中编写高效的多线程程序并且合理管理线程的使用。


http://www.kler.cn/a/465127.html

相关文章:

  • 成都和力九垠科技有限公司九垠赢系统Common存在任意文件上传漏洞
  • Redis的缓存雪崩,缓存击穿,缓存穿透
  • 32单片机从入门到精通之软件编程——中断处理(九)
  • 密钥管理系统在数据安全解决方案中的重要性
  • ES6中定义私有属性详解
  • 《GICv3_Software_Overview_Official_Release_B》学习笔记
  • TDengine 如何进行高效数据建模
  • 什么是Sight Words(信号词)
  • LabVIEW开发中常见硬件通讯接口快速识别
  • 安卓入门十一 常用网络协议四
  • 《大话设计模式》解读09-建造者模式
  • 「Java 数据结构全面解读」:从基础到进阶的实战指南
  • 鸿蒙HarmonyOS开发:基于Swiper组件和自定义指示器实现多图片进度条轮播功能
  • 基于python的随机迷宫游戏
  • element-ui的rules中正则表达式
  • 微服务三大配件深度解析、实现
  • 深圳南柯电子|净水器EMC测试整改:确保水质安全的电磁防护
  • 探索Milvus数据库:新手入门指南(tencent云)
  • 大带宽服务器和普通服务器相比较的优势
  • 局域网中单台交换机VLAN应用
  • rsync中远端文件的校验和存储缓存的黑科技
  • Docker--Docker Image(镜像)
  • Visual Point Cloud Forecasting enables Scalable Autonomous Driving——点云论文阅读(12)
  • STM32的LED点亮教程:使用HAL库与Proteus仿真
  • RT-Thread中堆和栈怎么跟单片机内存相联系
  • XIAO Esp32S3 播放网络Mp3