.NET中的线程

      早在2001年的时候,IBM就推出了在一个CPU上集成两个运算核心的服务器,但桌面双核的到来却是2005年4月18号,Intel发布了其历史上第一颗双核CPU-奔腾至尊版840,从此,千千万万的普通用户也进入了多核时代。随着多核的到来,以前随CPU频率的提高而带来的性能提升已经成为历史,软件开发人员必须去面对多核编程,而其中绕不过的一个中心就是多线程。本文围绕Windows平台展开,讨论.NET所支持的线程。

一、历史回顾

      众所周知,Windows早期是不支持多线程的,一个进程贯穿整个系统,同时,它也是一个线程。这使得同一时间内只能运行一个任务,如果这个任务运行时间过长,那么用户只有等待任务执行完毕。遗憾的是,如果程序中不小心出现了死循环,那么用户就只有按重启键重启操作系统了,这会导致某些重要的用户数据丢失,用户体验也非常差。微软为了解决这个问题,引入了进程的概念,进程是应用程序运行的实例,每个进程都有独立的内存空间,进程间不能相互访问。这种机制的好处是如果一个进程出现问题,如崩溃,不会影响到其它进程的正常运行,使Windows更加稳定,安全了。但问题又来了,如果一旦某个进程中的代码出现死循环,那么这个进程会占用全部CPU资源,而致使其它程序无法获得CPU资源,由于进程间的隔离性,其它应用程序也无法中止它。因此,微软又引入了线程机制,线程允许其它应用程序(例如任务管理器)强制中止某个线程的执行。值得一提的是,发布于1993年的Windows NT 3.1(首款Windows 32位操作系统)标志着Windows操作系统进入了多线程时代。

二、Windows线程详解

     线程是CPU的执行单元,一个进程可以包含一个或多个线程,同一进程间的多个线程共享进程资源。操作系统通过线程之间的切换执行实现了多任务的并发执行。在Windows中,创建一个线程的代价是很大的,虽然现在硬件的速度对于创建一个线程来说所用时间非常小,但我们了解这些细节对于我们是非常有用的。

    1、线程的开销

    ● 线程内核对象 当线程被创建时,操作系统要分配与初始化的数据结构。包括一系列描述线程的属性以及线程上下文。

    ● 线程环境块 是用户模式下分配和初始化的内存块,它包含线程异常处理链的头信息。每当线程中的代码进入try语句块时,就会插入一个标志在当前线程异常处理链的头信息中,当退出try语句块时,这个标志就会被移除。

    ● 用户模式栈 用于存储局部变量、传递给方法的参数,以及方法返回值,即我们通常所说的线程栈。

    ●  内核模式栈 用于存储应用程序传递参数给内核方法。

    ●  DLL线程附加和线程卸载通知标志 用于DLL的加载与卸载的相关工作。

    2、线程上下文切换

      不管是以前的单核CPU还是如今的多核CPU,至始至终,CPU是有限的,是众多程序必用的公共资源。理想的情况下,不用线程切换的程序的性能是最高的,但这又成了单线程了,不是我们想要的结果。所以,不管怎样,线程切换是必不可少的开销。由于CPU在某一时刻只能执行一个任务,因此,操作系统把CPU的时间分成极为细小的时间片(大约30毫秒),在某个时间片内,执行某个任务,时间片结束后,操作系统就会把当前正在执行的线程挂起,切换到下一个要执行的线程并执行,这就叫线程上下文切换。线程上下文切换的步骤是:

    (1)、保存CPU寄存器的值到当前线程内核对象中的线程上下文中

    (2)、选择并调度一个等待线程集合中的线程,如果这个线程与上一个线程不在同一个进程中,那么线程在正式开始前切换到当前进程的虚拟地址空间。

    (3)、加载线程上下文数据到CPU寄存器并开始执行

     经过这三步操作,操作系统就把一个线程切换到另一个线程,线程之间的切换就如此反复地进行着。

    3、线程的优先级

      Windows是一个抢占式的多线程操作系统,而这一切,由线程的优先级来决定。当Windows启动后,会有众多的线程等待执行,如此众多的线程到底先执行谁呢?这是一个问题,于是就有了线程优先级,当然是执行优先级高的线程了。线程的优先级不仅决定着线程的执行先后顺序,而且也决定着线程分得CPU时间片的多少。例如,当前有个优先级为3的线程A在执行,此时,半路杀出个优先级为5的线程B,由于Windows的抢占性,这时,不管线程A的CPU时间片还剩多少,也不管线程A执行到哪步了,彪悍的操作系统立即挂起线程A,切换到线程B执行。等线程B时间片结束后,操作系统会分一小片时间片给线程A执行,然后再分多一些的时间片给线程B执行,如此往复,直到两个线程执行完毕。

     就如线程的优先级一样,进程也有优先级,Windows把进程分为六个优先级,Idle, Below Normal, Normal, Above Normal, High, 以及Realtime,在.NET类库中,我们可以从System.Diagnostics.ProcessPriorityClass枚举中看到关于进程优先级的定义。Normal是默认的进程优先级,值得注意的是,我们要慎用Realtime优先级,因为这个优先级太高了,以致会干扰到操作系统的运行。

     Windows把线程分为32个优先级,从0到31。为了简化我们的记忆,它们被定义为Idle, Lowest, Below Normal, Normal, Above Normal,Highest, 以及Time-Critical。在.NET类库中,我们可以在System.Threading.ThreadPriority枚举中看到相关定义。为了方便说明进程优先级是如何影响线程优先级的,请看下表:

threadPriority

     我们可以通过设置线程的Priority属性来指定线程的优先级,值得注意的是,在.NET中,一旦指定了进程的优先级以后,就不能更改,因为,更改进程的优先级会涉及到大量线程的优先级也会做出更改,这样会影响到程序的运行。

三、.NET中的线程

     我们都知道,在.NET中,通过System.Threading.Thread类来创建一个线程,叫做托管线程。而实际发生的情况却不是我们想象中的那样,.NET并没有实际创建线程,而是利用Windows的线程处理能力。System.Threading.Thread实例只是包装了Win32线程。甚至有时候,.NET线程并没与Win32线程一一对应。

     1、前台线程VS后台线程

     当我们创建一个新线程时,通过指定IsBackground的值来设置这个线程是前台线程还是后台线程。简单的说,前台线程会一直运行直到任务完成或者强制中止,即使应用程序结束也仍会运行;而后台线程就不会这样,当程序结束,不管后台线程执行到什么状态,都会随应用程序的结束而中止。

     2、线程池

     通过第二节的描述我们知道,创建一个新线程开销相当的大,如果反复频繁的创建销毁线程,会影响程序性能,所以微软在.NET中加入了线程池。简单地说,线程池是一个线程集合,当我们把要执行的任务交给线程池去处理后,我们并不关心这个任务由哪个线程来执行,也不关心执行完任务后要不要立即销毁线程。这一切,都由线程池来打理。

      3、并行库

     为了减小并行代码的开发难度,微软在.NET 4.0中提供了并行库。所谓并行,就是通过多个线程同时执行一个任务,这样,分配的CPU时间片就更多,任务执行得也就越快。.NET 4.0通过System.Threading.Tasks.Parallel类提供并行处理能力。

四、总结

 

     多核时代,面对着繁重的处理任务,同时也为了使CPU的处理能力发挥出来,我们会创建更多的线程来完成我们的工作。但我们编程的复杂性也随之增加,遇到的问题也会更多,只有深入线程底层,了解线程的更多知识,对我们的工作会带来更多的帮助。

 

     参考文献:《CLR Via C#》,Third Edtion,作者:Jeffrey Richter,P691~719。

转载于:https://www.cnblogs.com/myshell/archive/2010/03/28/1699089.html

C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例),可直接运行 立即下载

相关推荐

基因家族的鉴定-基于Windows系统上的HMMER

基因家族的鉴定-基于Windows系统上的HMMER。

liangjinghui123的博客 3244

.NET 线程概述

概论 多线程在构建大型系统的时候是需要重点关注的一个重要方面,特别是在效率(系统跑得多快?)和性能(系统工作正常?)之间做一个权衡的时候。恰当的使用多线程可以极大的提高系统性能。什么是线程? 每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可

binyao02123202的专栏 1852

JasperReport制作行内容合并的表格

效果图: 实现思路一: 交叉表 另一个思路: 普通表格 缺点:无法实现内容 垂直居中显示 准备工作 一、数据准备 DROP TABLE IF EXISTS `address_item_sex_value`; CREATE TABLE `address_item_sex_value` ( `id` int(11) NOT NULL AUTO_INCREM...

weixin_34148456的博客 2468

.NET多线程

线程是操作系统中能够独立运行的最小单位,也是程序中可以并发执行的一段指令序列线程是进程的一部分,一个进程可以包含多个线程进程有入口线程,也可以创建更多线程一组预先创建好的线程备注:因为一个线程的创建和销毁是占用系统开销的,用线程池里提前创建好的线程,可以避免频分的创建和销毁新线程,可以提高系统效率。小的且不会阻塞的任务可以用线程池里的线程,其他的时候还是自己创建新线程吧。异步编程默认用的线程池里的线程。多个线程访问同一个资源,不会导致共享资源数据不一致或不可预期的结果就称为线程安全。

qq_31210287的博客 938

动态博弈、威胁与承诺(博弈论入门学习笔记四)

0 动态博弈 动态博弈:行动有先后顺序,不同的参与人在不同时点行动,先行动者的选择影响后行动者的选择空间,后行动者可以观察到先行动者做了什么选择。例如下棋、消费者和商家讨价还价、谈婚论嫁、企业之间的价格战等等。 因此,为了做出最优的行动选择,每个参与人都应该思考:如果我如此选择,对方将如何应对?如果我是他,我将会如何行动?给定他的应对,什么是我的最优选择? 动态博弈中的战略:在博弈开始之前就...

stepho的博客 1万+

【STM32项目】老人健康跌倒检测系统实现(附教程PCB资料)

功能概述 跌倒检测 倾倒告警,人体角度倾斜至阈值触发蜂鸣报警 异常运动,加速度超过正常行动阈值时触发报警 心率监测 实时检测心率数据 血氧监测 实时检测采集血氧 血压测量 血压在线测量 红外体温 非接触体温采集方案 接触式体温采集方案 实时定位 中科微GPSGT-U12双频GPS北斗 GLONASS IRNSS定位系统 NEMA数据解析 可扩展高精度定位方案厘米级 屏幕显示 数据采集显示 告警阈值设置 语音提示 1欢迎使用老人智慧监测系统

洋洋的博客 1万+

.net 多线程的四种实现方式

.net中创建多线程可以有四种方式: Thread类、委托、ThreadPool类、Task类 Thread类创建多线程 /// <summary> /// Thread类启动 /// </summary> public static void Thread_Start() { Thread thread = new Thread(...

weixin_30535565的博客 3634

关于 SAP UI5 应用 url 中的特殊符号 # 的作用介绍

符号在 SAP UI5 的 URL 中不仅仅是一个分隔符,更是动态路由、状态管理和深链接的关键所在。通过合理使用,开发者可以实现高效、流畅的用户体验,同时保持系统的可维护性和扩展性。通过 SAP UI5 提供的灵活路由机制,企业应用可以轻松实现复杂导航需求,同时为用户提供直观的交互体验。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 411

.NET Core 线程(Thread)底层原理浅谈

简介 内核态,用户态,线程,进程,协程基本概念不再赘述。 原生线程和用户线程 原生线程 在内核态中创建的线程,只服务于内核态 用户线程 由User Application创建的线程,该线程会在内核态与用户态中间来回穿梭 比如Throw Exception,就会由CLR 线程触发,从用户态切换到内核态,再切换回用户态。 时钟中断与时间片 时钟中断的底层,是由主板上的硬件定时器产生,以...

weixin_40506163的博客 253

【系统移植】 移植主线U-Boot(v2024.01-rc3)到RK3399

[系统移植] 移植主线U-Boot(v2024.01-rc3)到RK3399

Systemcall名屋 1004

论文必备 - 绘制YOLOv8模型在训练过程中,精准率,召回率,mAP_0.5,mAP_0.5:0.95,以及各种损失的变化曲线

文件是模型在训练过程中,实时记录训练的结果,和当时控制台输出的信息一致。当然还包含一些验证损失,学习率变化等数据。epoch:记录训练的轮次,总轮次为训练文件中设置的epochs大小。:边界框损失。在训练过程中,此值逐渐变小,越小表示模型预测的边界框与真实边界框之间的差异越小。:分类损失。在训练过程中,此值逐渐变小,越小表示模型对目标类别的预测越准确。:分布焦点损失。将边界框的回归问题转化为对边界框四个边的分布预测问题,越小表示预测越准确。:精确率也称为查准率。

Limiiiing的博客 1407

.net 线程粗解

做早餐,我们点火热平底锅后就去烤面包,但平底锅什么时候好,我们什么时候切换回来煎鸡蛋,还是去倒橙汁。异步方法同步运行,直至到达其第一个 await 表达式,此时会将方法挂起,直到等待的任务完成。至此,关于 C# 中异步编程的三个知识点 async,await,Task 讲解完毕。本人以前看到 同步 这个词,错误地顾名思义,以为是同一刻时间做几件事,错错错!这个时候方法虽然被声明为异步的,但现在执行过程还是同步的!// 这代码是有问题的,我有意为之,用来和接下来的更完善的代码做比较~

kalvin_y_liu的博客 207

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

.NET中的线程锁

常用的锁机制包括lock关键字、Monitor类、Mutex类以及Semaphore等。线程锁的使用可以有效避免数据竞争和不一致的状态,但也需要谨慎使用,避免死锁、性能问题等。欢迎关注我的公众号“Net分享”,技术文章第一时间推送,随缘更新 , 分享一些你可能注意不到的细节。

混迹自留地 1275

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

NET中的线程锁

在.NET中,线程锁(Thread Locking)是一种重要的同步机制,用于确保多个线程在访问共享资源时不会发生冲突,保证线程安全。线程锁的核心目标是避免数据竞争和不一致的状态,确保在同一时刻只有一个线程能够访问特定的资源或代码块。本文将详细讲解.NET中的线程锁,帮助你理解其工作原理、常见实现方式及注意事项。常见的线程锁有:• 自旋锁:当线程尝试获取锁时,它会重复执行一些简单的指令,直到锁可用...

dotNET跨平台 249

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

浅谈.net中的多线程

什么是线程 每个正在系统上运行的程序都是一个进程,每个进程包含一到多个线程,进程也可能是整个程序或者是部分程序的动态执行,线程是一组指令的集合,或者是程序的特殊段,它可以在整个程序里独立执行,也可以把它理解为代码运行的上下文,所以线程基本上是轻量级的进程,它负责在单元程序里执行多任务,通常有操作系统负责多个线程的调度和执行。 什么是多线程 多线程是为了使得多个线程并行的工作以完成多项任务,

Keymo_的奋斗史 1616

转:.NET中的线程

<br />此文比较详细的讲述了.NET中的线程,很好的学习资料,新手值得学习。<br /><br />目录<br /><br /><br /> <br />基础篇怎样创建一个线程受托管的线程与 Windows线程前台线程与后台线程名为BeginXXX和EndXXX的方法是做什么用的 异步和多线程有什么关联<br />WinForm多线程编程篇我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决?Invoke,BeginInvoke干什么用的,内部是怎么实现的每

tanhua103292的专栏 751

在.NET中的线程处理(2)

.NET 框架提供了许多有助于您创建和管理多线程应用程序的对象。WaitHandle 对象可以帮助您响应其他线程执行的操作,尤其是在与非托管代码交互操作时。ThreadPool 为大多数任务提供最佳的基本线程创建和管理机制。Monitor、Mutex、Interlocked 和 ReaderWriterLock 提供用于在较低级别上同步执行的机制。Timer 是一种非常灵活的用来以特定时间间隔引发

公主笔记(快乐的蓝精灵) 535

vb.net中线程怎么使用_VB.NET中的线程介绍

vb.net中线程怎么使用 To understand threading in VB.NET, it helps to understand some of the foundation concepts. First up is that threading is something that happens because the operating system supports it. ...

cumao2792的博客 1434

讲述.NET中的线程(转)

写在前面,原文:http://www.cnblogs.com/yizhu2000/archive/2008/01/03/1011958.html此文比较详细的讲述了.NET中的线程,很好的学习资料,新手值得学习。目录 基础篇 怎样创建一个线程受托管的线程与 Windows线程前台线程与后台线程名为BeginXXX和EndXXX的方法是做什么用的 异步和多线程有什么关联

275

在.NET中的线程处理(1)

无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为用户提供最好的响应性能,即使应用程序当前正在完成其他工作。要使应用程序能够快速响应用户操作,同时在用户事件之间或者甚至在用户事件期间利用处理器,最强大的方式之一是使用多个执行线程。线程与线程处理操作系统使用进程将它们正在执行的不同应用程序分开。线程是操作系统分配处理器时间的基本单元,并且该进程中可以有多

Paul_Ni的专栏 2346

ASP.NET中的多线程整理

  线程,是操作系统中的术语,是操作系统进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以有很多线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(...

a3391111的博客 462

.net中的多线程

一.多线程的概念 什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是...

weixin_30699831的博客 105

DotNetGuide进程与线程:.NET中的并发模型

你是否在.NET开发中遇到过这些问题:界面卡顿无响应、数据处理效率低下、高并发场景下程序崩溃?根据Stack Overflow 2024年开发者调查,**73%的.NET开发者**认为并发编程是日常工作中最具挑战性的任务之一。本文将系统解析进程与线程的底层原理,全面对比.NET中的4种异步模式与4种多线程实现方式,提供12个实战案例和8个性能优化技巧,帮你彻底掌握并发编程精髓。 读完本文你将获得...

gitblog_00620的博客 1217
上一篇: .NET 4.0 任务(Task)
下一篇: Visual Studio 2010 RTM版安装初体验
devo4561
博客等级 码龄12年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值