.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 :托管线程的创建和管理相对于原生线程更简化,例如使用 Taskasync/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.RunTask.Factory.StartNew 方法在后台线程中执行异步任务。Task 类是更高层次的抽象,通常更推荐用于多线程编程。
  • 线程池 :通过 ThreadPool 类或 Task 类实现线程池任务,避免了手动管理线程创建和销毁的开销。

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

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

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

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

9. 线程的调度

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

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

总结

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

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

相关推荐
Libby博仙5 小时前
创建.net core 8.0项目时,有个启用原生AOT发布是什么意思
microsoft·asp.net·.netcore
时光の尘6 小时前
嵌入式Linux(二)·配置VMware使用USB网卡连接STM32MP157实现Windows、Ubuntu以及开发板之间的通信
linux·服务器·c语言·windows·stm32·ubuntu
我从不骗人6 小时前
Windows系统安装Docker Desktop
windows·docker·容器
途途途途7 小时前
奇怪的Python:为何 list 和 dict 的元素顺序从 Python 3.7 开始保持插入顺序?
windows·python·list
小参宿13 小时前
【开源监控工具】Uptime Kuma:几分钟设置实时监控你的网站性能
linux·运维·服务器·windows·容器·开源·计算机组成
Xzzzz91114 小时前
华为配置 之 链路聚合
linux·服务器·网络·windows·计算机网络·华为
Datrilla15 小时前
atrust异常导致ERR_NETWORK_CHANGED
windows·http
Clockwiseee15 小时前
文件上传漏洞利用与绕过姿势总结
linux·windows·安全·web安全·网络安全·php
mingupup17 小时前
PaperAssistant:使用Microsoft.Extensions.AI实现
人工智能·microsoft
等一场春雨19 小时前
MySQL Windows 11 的 MySQL 配置文件 (my.ini) 路径查找指南
windows·mysql·adb