C#基础--进程和线程的认识

C#基础–进程和线程的认识

一、基础概念

1. 什么是进程?

进程并不是物理的东西,是虚拟出来的,是一种概念。当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。是一种计算机概念,是程序在运行的时候,记录当前程序对计算机的各种资源的消耗。

如任务管理器中的应用进程等

image-20220327112943519

2. 什么是线程?

线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。也是一种计算机概念,线程是进程在响应操作的时候一个最小的单元,也包括CPU/硬盘/内存等。

image-20220327113310833

3. 什么是句柄?

描述程序中的某一个最小单元,是一个long数字,操作系统通过这个数组识别应用程序。

4. 什么是多线程?

多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

**多线程的好处: **
可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。

多线程的不利方面:
线程也是程序,所以线程需要占用内存,线程越多占用内存也越多; 
多线程需要协调和管理,所以需要CPU时间跟踪线程; 
线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
线程太多会导致控制太复杂,最终可能造成很多Bug;

5. 何时使用多线程?

​ 多线程程序一般被用来在后台执行耗时的任务。主线程保持运行,并且工作线程做它的后台工作。对于Windows Forms程序来说,如果主线程试图执行冗长的操作,键盘和鼠标的操作会变的迟钝,程序也会失去响应。由于这个原因,应该在工作线程中运行一个耗时任务时添加一个工作线程,即使在主线程上有一个有好的提示“处理中…”,以防止工作无法继续。这就避免了程序出现由操作系统提示的“没有相应”,来诱使用户强制结束程序的进程而导致错误。模式对话框还允许实现“取消”功能,允许继续接收事件,而实际的任务已被工作线程完成。BackgroundWorker恰好可以辅助完成这一功能。

​ 在没有用户界面的程序里,比如说Windows Service, 多线程在当一个任务有潜在的耗时,因为它在等待另台电脑的响应(比如一个应用服务器,数据库服务器,或者一个客户端)的实现特别有意义。用工作线程完成任务意味着主线程可以立即做其它的事情。

​ 另一个多线程的用途是在方法中完成一个复杂的计算工作。这个方法会在多核的电脑上运行的更快,如果工作量被多个线程分开的话(使用Environment.ProcessorCount属性来侦测处理芯片的数量)。

​ 一个C#程序称为多线程的可以通过2种方式:明确地创建和运行多线程,或者使用.NET framework的暗中使用了多线程的特性——比如BackgroundWorker类, 线程池threading timer,远程服务器,或Web Services或ASP.NET程序。在后面的情况,人们别无选择,必须使用多线程;一个单线程的ASP.NET web server不是太酷,即使有这样的事情;幸运的是,应用服务器中多线程是相当普遍的;唯一值得关心的是提供适当锁机制的静态变量问题。

6. 何时不要使用多线程?

​ 多线程也同样会带来缺点,最大的问题是它使程序变的过于复杂,拥有多线程本身并不复杂,复杂是的线程的交互作用,这带来了无论是否交互是否是有意的,都会带来较长的开发周期,以及带来间歇性和非重复性的bugs。因此,要么多线程的交互设计简单一些,要么就根本不使用多线程。除非你有强烈的重写和调试欲望。

​ 当用户频繁地分配和切换线程时,多线程会带来增加资源和CPU的开销。在某些情况下,太多的I/O操作是非常棘手的,当只有一个或两个工作线程要比有众多的线程在相同时间执行任务块的多。稍后我们将实现生产者/耗费者 队列,它提供了上述功能。

7. 进程和线程的关系?

它们两是一种包含关系,线程是属于某一个进程的,如果一个进程被销毁了,那隶属于该进程的线程也就不存在了。

二、Thread – 线程

Thread 来自于 System.Threading 的一个密封类,它是.Net Framework 1.0 时代出现的,在C# 中用来操作线程的一个帮助类库;

1. 为什么可以多线程?

  • 一个CPU有多个核,可以并行计算

    image-20220327130008749

  • 例如我们通常叫的“双核四线程”,这里的线程其实是模拟核

2. 什么叫CPU的分片,为什么要对CPU分片呢?

某1s 的处理能切分成 1000 份,操作系统调度去相应不同的任务;

从宏观的角度来说,感觉就有多个任务在并发执行;

从微观的角度来说,一个物理CPU不能在某一时刻为一个任务服务;

3. 同步方法和异步方法的区别?

同步方法:同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果;

private void btnSync_Click(object sender, EventArgs e)
{
     for (int i = 0; i < 5; i++)
     {
         string name = string.Format($"btnSync_Click_{i}");
         this.DoSomethingLong(name);
     }
}
private void DoSomethingLong(string name)
{
    long lResult = 0;
    for (int i = 0; i < 1_000_000_000; i++)
    {
        lResult += i;
    }
}

异步方法:在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作。

Action<string> action = this.DoSomethingLong;
 for (int i = 0; i < 5; i++)
 {
     action.BeginInvoke("btnAsync_Click", null, null);
 }

private void DoSomethingLong(string name)
{
	Console.WriteLine($"****************DoSomethingLong Start  {name}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
    long lResult = 0;
    for (int i = 0; i < 1_000_000_000; i++)
    {
        lResult += i;
    }
    Console.WriteLine($"****************DoSomethingLong   End  {name}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
}

体验对比

  • 同步方法卡界面:主线线程(UI线程)忙于计算,无暇他顾

  • 异步方法不卡界面:因为异步方法是新启动一个线程去完后计算,主线程闲置;改善用户体验,winform程序点击某一个按钮,不会卡死界面;发短信,发邮件可以交给一个子线程去完成

速度对比

  • 同步方法执行慢:只有一个线程完成计算

  • 异步方法执行快:多个线程去完成计算,资源换性能

执行顺序对比

  • 同步方法有序执行

  • 异步多线程无顺序:启动无序,结束无序。线程资源是向操作系统申请的,操作系统有自己的调度策略,所以启动是随机的,结束也是没有顺序

4. 如果需要用到线程又需要控制顺序呢?怎么实现?

利用回调

AsyncCallback callback = (ar) => ar 是 IAsyncResult 类型数据

Func<string, string> func = (ar) => ar 是委托中定义的第一个参数,是string类型数据

private void btnAsyncAdvanced_Click(object sender, EventArgs e)
{
   //回调:把后续的动作通过回调参数传递进去,子线程完成计算以后,去嗲用这个回调委托
   //AsyncCallback 委托要用的方法必须是IAsyncResult 参数,该参数存了回调方法所需参数为object对象。
   AsyncCallback callback = ar =>
   {
       Console.WriteLine($"计算结束了。。。。{Thread.CurrentThread.ManagedThreadId}");
   };
   
   Func<string, string> func = (ar) => {
       Console.WriteLine($"线程Id:{Thread.CurrentThread.ManagedThreadId}");
       Thread.Sleep(5 * 1000);
       return "Hyl";
   };
   
   func.BeginInvoke("大白", callback, null); 
}

image-20220327155610952

利用 func.EndInvoke 接收Func 委托中的方法执行后的返回值

//IASyncResult参数1-N由自定义委托AddDelegate决定,AddDelegate有N个参数,那么就有N个参数
IAsyncResult asyncResult = func.BeginInvoke("大白", callback, null); 

var result = func.EndInvoke(asyncResult);
Console.WriteLine("执行结果=" + result);

image-20220327160133388

5. 等待任务完成

5.1 Func.EndInvoke() 等待任务完成

委托.EndInvoke(asyncResult) 相当于一个监视器,一直在监视异步委托执行完成。一旦完成,则获取到结果并赋值到result中,与此同时会异步调用回调函数(有回调的情况下)。

AsyncCallback callback = (ar) =>
{
    Console.WriteLine(JsonConvert.SerializeObject(ar));
    Console.WriteLine($"计算结束了。。。。{Thread.CurrentThread.ManagedThreadId}");
};

IAsyncResult asyncResult = func.BeginInvoke("大白", callback, null);	

var result = func.EndInvoke(asyncResult);
Console.WriteLine("获取执行结果=" + result);

image-20220327161735286

无论委托中的方法执行多久,增加了 func.EndInvoke(asyncResult) 的话,其之后的代码执行便形成了阻塞(变成了一种同步形式),需要等委托的方法执行结束,result 接收到返回数据才能往下执行(按钮同步执行接收)

//此处的asyncResult 和回调函数中的 ar 是同一个类,同样的数据
//回调函数中使用 object.ReferenceEquals(ar, asyncResult); => 结果为:true
IAsyncResult asyncResult = func.BeginInvoke("大白", callback, null);	
Console.WriteLine("--------------func.BeginInvoke 异步执行开始------------------");

var result = func.EndInvoke(asyncResult);
Console.WriteLine("func.EndInvoke 获取执行结果=" + result);

Console.WriteLine("--------------btnAsyncAdvanced_Click 同步执行结束------------------");

image-20220327163709526

IAsyncResult 数据解析:

{
  "IsCompleted": true,
  "AsyncDelegate": {		//委托方法信息
    "Method": {
      "Name": "<btnAsyncAdvanced_Click>b__4_1",
      "AssemblyName": "MyAsyncThread, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
      "ClassName": "MyAsyncThread.frmThreads+<>c",
      "Signature": "System.String <btnAsyncAdvanced_Click>b__4_1(System.String)",
      "Signature2": "System.String <btnAsyncAdvanced_Click>b__4_1(System.String)",
      "MemberType": 8,
      "GenericArguments": null
    },
    "Target": {}
  },
  "AsyncState": null,	//func.BeginInvoke("大白", callback, 52032); 如最后一个参数设置了值,则AsyncState便是什么值 "AsyncState": 52032
  "CompletedSynchronously": false,
  "EndInvokeCalled": true,	//如果Func委托未使用EndInvoke的时候,此属性为 false
  "AsyncWaitHandle": {	//句柄
    "Handle": {
      "value": 1796
    },
    "SafeWaitHandle": {
      "IsInvalid": false,
      "IsClosed": false
    }
  },
  "NextSink": null
}

5.2 IsCompleted() 等待任务完成

使用等待的过程中,界面会被卡到

while (!asyncResult.IsCompleted) {
    Thread.Sleep(1000);
    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + " 线程暂未结束");
}

var re = func.EndInvoke(asyncResult);
Console.WriteLine("func.EndInvoke 获取执行结果=" + re);

image-20220327172744784

5.3 WaitOne() 完成任务等待

asyncResult.AsyncWaitHandle.WaitOne();  //一直等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(-1);  //一直等待任务完成,-1无限期等待
asyncResult.AsyncWaitHandle.WaitOne(3000);  //最多等待3000毫秒=3秒,如果超时则不等待了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小白入门C#编写MVC登录小案例

一、C#编写MVC登录小案例 &#x1f680;1. 新建MVC项目。 &#x1f680;2. 在Models文件夹下创建一个User类&#xff0c;包含登录所需要的用户名和密码属性。 namespace MvcLogin.Models {public class User{public string UserName{get; set;}public string Password{get;se…

unity01 界面布局

布局 坐标系 遵循左手定则&#xff0c;中指是y轴、食指是x轴、大拇指是z轴。 可以理解为x轴代表东西方向&#xff0c;z轴代表南北方向&#xff0c;y轴代表上下方向。 常用快捷键 鼠标中键&#xff1a;移动地图 右键&#xff1a;移动视角 shift鼠标左键单击gimo导航器的小方…

【C++】设计模式-单例模式

目录 一、单例模式 单例模式的三个要点 针对上述三要点的解决方案 常用的两类单例模式 二、懒汉模式实现 1.基本实现 2.锁静态成员析构单例 3.双层检查锁定优化 4.双层检查锁定智能指针 三、饿汉模式实现 1.基础实现 2.嵌套内部类解决内存泄漏 3.智能指针解决内存泄…

linux 系统修改已经打好jar包的yml配置文件

工作中可能回遇到&#xff0c;jar包已经打好&#xff0c;并且文件已经上传了&#xff0c;但是突然发现配置文件中的某一个参数写错了&#xff0c;怎么办&#xff1f;重新打包&#xff1f;如果重新打包再上传的话太影响效率了。那么我们可以通过以下方法&#xff0c;修改已经上传…

SuperMap iServer新增支持FlatGeobuf数据格式,查询渲染性能提升2-3倍

导语 FlatGeobuf是一种地理数据存储格式&#xff0c;采用了二进制编码&#xff0c;相比其他文本或XML格式更高效&#xff0c;可以显著减小文件大小&#xff0c;这使得数据的传输和存储更加快速和高效。 SuperMap iServer 11i(2023) &#xff08;以下简称SuperMap iServer11.1&a…

Pandas Groupby:在Python中汇总、聚合和分组数据

GroupBy是一个非常简单的概念。我们可以创建一个类别分组&#xff0c;并对这些类别应用一个函数。这是一个简单的概念&#xff0c;但它是一种在数据科学中广泛使用的非常有价值的技术。在真实的的数据科学项目中&#xff0c;您将处理大量数据并一遍又一遍地尝试&#xff0c;因此…

elementUI el-radio 无法点击的问题

<el-form-item label"B端客户类型" prop"user_type"><template slot"label"><span>B端客户类型</span><el-tooltip effect"dark" placement"top" content"B端大客户账期有效,只有设置该类型…

【Go】实现一个代理Kerberos环境部分组件控制台的Web服务

实现一个代理Kerberos环境部分组件控制台的Web服务 背景安全措施引入的问题SSO单点登录 过程整体设计路由反向代理登录会话组件代理YarnHbase 结果 背景 首先要说明下我们目前有部分集群的环境使用的是HDP-3.1.5.0的大数据集群&#xff0c;除了集成了一些自定义的服务以外&…

寻找下一个生成式 AI 独角兽,亚马逊云科技创业加速器火热招募中!

生成式AI让人工智能技术又一次破圈&#xff0c;带来了机器学习被大规模采用的历史转折点。它正在掀起新一轮的科技革命&#xff0c;为人类带来前所未有的颠覆性的影响&#xff0c;而诸多创业者也应势而上&#xff0c;寻求创新机遇。生成式AI可以创造全新的客户体验、提高企业内…

fastapi初使用,构建自己的api

文章目录 1、安装2、api实现2.1、 app.get("/1")2.2、app.get("/{a}")2.3、app.get("/{a}{b}")2.4、函数和api分离 3、运行 原文链接&#xff1a;https://wangguo.site/posts/d98bb3c9.html fastapi 是一个基于 Python 的 API 构建框架&#xff…

044、TiDB特性_PlacementPolicy

Placement Rules in SQL之前 跨地域部署的集群&#xff0c;无法本地访问无法根据业务隔离资源难以按照业务登记配置资源和副本数 Placement Rules in SQL之后 跨地域部署的集群&#xff0c;支持本地访问根据业务隔离资源按照业务等级配置资源和副本数 配置 labels 设置 Ti…

Windows Cluster 分布式算法

在分布式系统中&#xff0c;都需要解决分布式一致性问题。那么&#xff0c;在Windows 集群中&#xff0c;使用了什么算法来保证集群的一致性呢——Paxos。Windows Server 故障转移集群 (WSFC) 使用 Paxos 算法在整个系统中同步更改。通过记录 Paxos Tag 值并保留历史记录&#…

vue 如何发布并部署到服务器

一般情况npm run build即可 从而生成vue代码直接放到服务器即可 这里的具体情况要看package.json里面的配置从而使用命令 会生成dist就是该项目的发布包

Inno Setup打包winform、wpf程序可判断VC++和.net环境

Inno Setup打包winform、wpf程序可判断VC和.net环境 1、下载Inno Setup2、新建打包文件、开始打包1、新建打包文件2、填写 应用名称、版本号、公司名称、公司官网3、选择安装路径 Custom是指定默认路径、Program Files folder是默认C盘根目录4、选择程序启动exe文件 以及Addfol…

Ubuntu下安装、配置及重装CUDA教程

安装CUDA 前往Nvidia CUDA Tools官网选择对应的架构和版本下载CUDA 以如下架构和版本为例&#xff1a; 查看显卡驱动 nvidia-smi如果显卡驱动已经装了&#xff0c;那么在CUDA安装过程中不用再勾选安装driver 下载并安装CUDA wget https://developer.download.nvidia.co…

ETHERCAT转ETHERCAT网关西门子为什么不支持ethercat两个ETHERCAT设备互联

1.1 产品功能 远创智控YC-ECT-ECT是自主研发的一款ETHERCAT从站功能的通讯网关。该产品主要功能是将2个ETHERCAT网络连接起来。 本网关连接到ETHERCAT总线中做为从站使用。 1.2 技术参数 1.2.1 远创智控YC-ECT-ECT技术参数 ● 网关做为ETHERCAT网络的从站&#xff0c;可以连接…

HTML5学习简记

目录 HTML定义 标签 HTML基本骨架 常见标签 标题标签 段落标签 换行与水平线标签 文本格式化标签 图像标签 绝对路径与相对路径 超链接标签 音频与视频标签 列表标签 无序列表 有序列表 定义列表 表格标签 表格结构标签 合并单元格 表单标签 input标签 input标签占…

CSS---CSS面试题

目录 1.盒模型 2.offsetHeight /clientheight/scrollHeight 3.left与offsetLeft 4.对BFC规范的理解 5.解决元素浮动导致的父元素高度塌陷的问题 6.CSS样式的先级 7.隐藏页面元素 8.display: none 与 visibility: hidden 的区别 9.页面引入样式时&#xff0c;使用link与import有…

GO 语言GC

目录 写屏障 读屏障 GO语言GC准备 堆内存结构: GC内存分配: GC触发&#xff1a; P的作用: 写屏障 实现强弱三色不式,为了避免误删,则实现写屏障. 写屏障是在写操作中插入指令,目的是把数据对象的修改通知到GC GO语言支持两种写屏障 读屏障 非移动垃圾回收(例如 三色)天…

文件共享服务器

文章目录 一、共享服务器概述二、创建共享三、访问共享四、创建隐藏的共享五、访问隐藏共享的方法六、共享相关命令七、屏蔽系统隐藏共享自动产生1. 打开注册表2. 定位共享注册表位置 八、查看本地网络连接状态&#xff08;查看开放端口&#xff09;九、关闭445服务 一、共享服…