.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 中编写高效的多线程程序并且合理管理线程的使用。

托管线程(Managed Thread)是 .NET 框架中的一个概念,它指的是由 .NET 的运行时环境(CLR,Common Language Runtime)管理的线程。与传统的操作系统线程(如 Windows 的线程或 Linux 的线程)不同,托管线程由 .NET 运行时创建和管理,它提供了更高层的抽象,可以帮助开发者更容易地进行多线程编程。

托管线程的特点

  1. 由 CLR 管理: 托管线程是由 .NET 的垃圾回收机制、调度器和其他系统服务(如线程池)自动管理的。当你在 C# 中创建一个新线程时,CLR 会自动管理它的生命周期。开发者不需要手动管理线程的创建、调度和销毁,CLR 会自动处理这些任务。

  2. 与操作系统线程的关系: 托管线程底层是通过操作系统的线程来实现的,因此它们也是操作系统线程的封装。托管线程可以运行在操作系统的线程池上,或者直接创建一个新的线程(例如,使用 Thread 类)。

  3. 线程池: 在 .NET 中,线程池是一个托管线程的集合,线程池中的线程是由 CLR 动态管理的。线程池用于执行那些不需要持续运行的工作任务。通过线程池,.NET 能够重用线程,从而避免了频繁创建和销毁线程所带来的性能损耗。

  4. 同步与异步操作: 托管线程是处理并发操作的基本单元。你可以在托管线程中执行同步操作,也可以在托管线程上执行异步操作(通过 asyncawait 机制)。在异步操作中,虽然操作不阻塞当前线程,但底层仍然会使用线程池中的托管线程来处理任务。

async 和 await 与托管线程

对于 asyncawait,它们并不直接创建托管线程,而是利用 任务(Task) 来管理异步操作。这些异步任务有时会在后台线程或线程池中执行,但 asyncawait 本身并不依赖于托管线程池。

具体来说,asyncawait 工作的原理可以用以下方式理解:

  • async 标记方法为异步方法,使得该方法返回一个 Task(或者 Task<T>)。它表示这个方法内包含可以等待的异步操作。
  • await 用于等待一个异步任务的完成。在等待期间,当前执行线程不会被阻塞,CLR 会去做任务调度,等待结果后继续执行后面的代码。

在异步编程中,托管线程可以用于执行那些需要等待的操作,尤其是涉及 I/O 密集型操作(比如文件读取、网络请求等)。异步操作本身并不创建新线程,而是让现有的线程去做其他事情,直到异步操作完成。

例子:托管线程与 async/await 的区别

使用 Thread 创建一个新线程
Thread newThread = new Thread(() =>
{// 这里执行一些任务
});
newThread.Start();

在这个例子中,我们显式创建了一个新的线程,这个线程是由操作系统创建并管理的,它属于托管线程的一部分。

使用 Task 和 async/await
public async Task<string> FetchDataAsync()
{var result = await httpClient.GetStringAsync("http://example.com");return result;
}

这里,FetchDataAsync 方法是异步的,虽然它可能会使用线程池中的托管线程来执行 I/O 操作(例如网络请求),但 async/await 并不直接创建线程。它只是让异步任务的执行不阻塞当前线程。

总结

  • 托管线程 是 .NET 环境中由 CLR 管理的线程,可以是操作系统线程,也可以是线程池中的线程。
  • async 和 await 并不会直接创建托管线程,它们的作用是使异步操作能够在不阻塞当前线程的情况下执行,通常是在 I/O 密集型操作中使用。异步操作会在后台线程上运行,但并不是每个 await 操作都会创建新的托管线程,很多时候是依赖现有线程池中的线程来处理这些任务。

因此,async/await 让异步编程更加简洁和高效,尤其适用于 I/O 密集型任务,而托管线程则是基础设施,允许程序并发执行多个任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503041.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac软件介绍之录屏软件Filmage Screen

软件介绍 Filmage Screen 是一款专业的视频录制和编辑软件&#xff0c;适用于 Mac 系统 可以选择4k 60fps&#xff0c;可以选择录制电脑屏幕&#xff0c;摄像头录制&#xff0c;可以选择区域录制。同时也支持&#xff0c;简单的视频剪辑。 可以同时录制电脑麦克风声音 标准…

欧科云链研究院:ChatGPT 眼中的 Web3

编辑&#xff5c;OKG Research 转眼间&#xff0c;2024年已经进入尾声&#xff0c;Web3 行业经历了热闹非凡的一年。今年注定也是属于AI的重要一年&#xff0c;OKG Research 决定拉上 ChatGPT 这位“最懂归纳的AI拍档”&#xff0c;尝试把一整年的研究内容浓缩成精华。我们一共…

.NET 9.0 WebApi 发布到 IIS 详细步骤

微软表示&#xff0c;.NET 9 是迄今为止性能最高的 .NET 版本&#xff0c;对运行时、工作负载和语言方面进行了 1,000 多项与性能相关的改进&#xff0c;并采用了更高效的算法来生成更好的代码。 .NET 9 是 .NET 8 的继任者&#xff0c;特别侧重于云原生应用和性能。 作为标准期…

【通识安全】煤气中毒急救的处置

1.煤气中毒的主要症状与体征一氧化碳中毒&#xff0c;其中毒症状一般分为轻、中、重三种。 (1)轻度&#xff1a;仅有头晕、头痛、眼花、心慌、胸闷、恶心等症状。如迅速打开门窗&#xff0c;或将病人移出中毒环境&#xff0c;使之吸入新鲜空气和休息&#xff0c;给些热饮料&am…

ECCV`24 | 首次解决文本到3D NeRFs分解问题!港中文等提出DreamDissector

论文链接&#xff1a;https://arxiv.org/abs/2407.16260 亮点直击 据作者所知&#xff0c;作者是第一个解决文本到3D NeRFs分解问题的团队。 为了解决这个问题&#xff0c;本文引入了一个名为DreamDissector的新颖框架&#xff0c;包括一种新颖的神经类别场&#xff08;NeCF&a…

nginx-灰度发布策略(split_clients)

一. 简述&#xff1a; 基于客户端的灰度发布&#xff08;也称为蓝绿部署或金丝雀发布&#xff09;是一种逐步将新版本的服务或应用暴露给部分用户&#xff0c;以确保在出现问题时可以快速回滚并最小化影响的技术。对于 Nginx&#xff0c;可以通过配置和使用不同的模块来实现基于…

PCL点云库入门——PCL库点云特征之PFH点特征直方图(Point Feature Histograms -PHF)

1、算法原理 PFH点&#xff08;Point Feature Histogram&#xff09;特征直方图的原理涉及利用参数化查询点与邻域点之间的空间差异&#xff0c;并构建一个多维直方图以捕捉点的k邻域几何属性。这个高维超空间为特征表示提供了一个可度量的信息空间&#xff0c;对于点云对应曲面…

qml PathView详解

1、概述 PathView 是 Qt Quick 中一个非常强大的视图组件&#xff0c;它基于一个 Path 来展示视图项&#xff08;如 Item、Rectangle 等&#xff09;。PathView 可以让你按照定义的路径动态地显示多个元素&#xff0c;并且支持动画、滑动等功能。这个视图控件的最大特点是能够…

网络协议安全的攻击手法

1.使用SYN Flood泛洪攻击&#xff1a; SYN Flood(半开放攻击)是最经典的ddos攻击之一&#xff0c;他利用了TCP协议的三次握手机制&#xff0c;攻击者通常利用工具或控制僵尸主机向服务器发送海量的变源端口的TCP SYN报文&#xff0c;服务器响应了这些报文后就会生成大量的半连…

前端学习DAY31(子元素溢出父元素)

.box1{width: 200px;height: 200px;background-color: chocolate;} 子元素是在父元素的内容区中排列的&#xff0c;如果子元素的大小超过了父元素&#xff0c;则子元素会从 父元素中溢出&#xff0c;使用overflow属性设置父元素如何处理溢出的子元素 可选值&#xff1a;visible…

机器人手眼标定

机器人手眼标定 一、机器人手眼标定1. 眼在手上标定基本原理2. 眼在手外标定基本原理 二、眼在手外标定实验三、标定精度分析 一、机器人手眼标定 要实现由图像目标点到实际物体上抓取点之间的坐标转换&#xff0c;就必须拥有准确的相机内外参信息。其中内参是相机内部的基本参…

【前端下拉框】获取国家国旗

一、先看效果 二、代码实现&#xff08;含国旗&#xff09; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

Timer、Ticker使用及其注意事项

Timer、Ticker使用及其注意事项 在刚开始学习golang语言的时候就听说Timer、Ticker的使用要尤其注意&#xff0c;很容易出现问题&#xff0c;这次就来一探究竟。 本文主要脉络&#xff1a; 介绍定时器体系&#xff0c;并介绍常用使用方式和错误使用方式源码解读 timer、tic…

C++11——2:可变模板参数

一.前言 C11引入了可变模板参数&#xff08;variadic template parameters&#xff09;的概念&#xff0c;它允许我们在模板定义中使用可变数量的参数。这样&#xff0c;我们就可以处理任意数量的参数&#xff0c;而不仅限于固定数量的参数。 二.可变模板参数 我们早在C语言…

君正T41交叉编译ffmpeg、opencv并做h264软解,利用君正SDK做h264硬件编码

目录 1 交叉编译ffmpeg----错误解决过程&#xff0c;不要看 1.1 下载源码 1.2 配置 1.3 编译 安装 1.3.1 报错&#xff1a;libavfilter/libavfilter.so: undefined reference to fminf 1.3.2 报错&#xff1a;error: unknown type name HEVCContext; did you mean HEVCPr…

感知器的那些事

感知器的那些事 历史背景Rosenblatt和Minsky关于感知机的争论弗兰克罗森布拉特简介提出感知器算法Mark I感知机争议与分歧马文明斯基简介单层感知器工作原理训练过程多层感知器工作原理单层感知机 vs 多层感知机感知器模型(Perceptron),是由心理学家Frank Rosenblatt在1957年…

C语言:枚举类型

一、枚举类型的声明 枚举顾名思义就是一一列举。我们可以把可能的取值一一列举。比如我们现实生活中&#xff1a; 星期一到星期日是有限的7天&#xff0c;可以一一列举 &#xff1b;性别有&#xff1a;男、女、保密&#xff0c;也可以一一列举 &#xff1b;月份有12个月&#x…

25/1/6 算法笔记<强化学习> 初玩V-REP

我们安装V-REP之后&#xff0c;使用的是下面Git克隆的项目。 git clone https://github.com/deep-reinforcement-learning_book/Chapter16-Robot-Learning-in-Simulation.git 项目中直接组装好了一个机械臂。 我们先来分析下它的对象树 DefaultCamera:摄像机&#xff0c;用于…

CODESYS MODBUS TCP通信(AM400PLC作为主站通信)

禾川Q1 PLC MODBUS-TCP通信 禾川Q1 PLC MODBUS-TCP通信(CODESYS平台完整配置+代码)-CSDN博客文章浏览阅读17次。MATLAB和S7-1200PLC水箱液位高度PID控制联合仿真(MODBUSTCP通信)_将matlab仿真导入plc-CSDN博客文章浏览阅读722次。本文详细介绍了如何使用MATLAB与S7-1200PLC进行…

OSPF - 影响OSPF邻居建立的因素

总结为这么10种 routerID 冲突区域id不一致认证MA网络掩码需一致区域类型(特殊区域)hello、dead时间MTU(如果开启检查)静默接口网络类型不匹配MA网络中路由器接口优先级全为0 如何建立邻居可以查看上一篇文章&#xff0c;可以直接专栏找&#xff08;&#x1f92b;挂链接会没流…