(一)CSharp-多线程编程

news/2024/4/17 11:11:45

一、进程与线程

1、进程
一个正在运行的程序的实例,是系统进行调度和资源分配的一个独立单位。

进程由两部分能组成:

(1)操作系统用来管理进程的内核对象。内核对象是系统的一种资源,系统对象一旦产生,任何应用程序都可以开启并使用该对象。系统给予内核对象一个计数值作为管理之用。

(2)操作系统用来管理地址的空间。它包含所有可执行模块或 DLL 模块的代码和数据。它还包含动态内存分配的空间,如线程堆栈和堆栈分配空间。

进程分为系统进程和用户进程。程序是静止的,二进程是动态的。

2、线程

一段完成某个特定功能的代码,是程序中的一个执行流。

线程由两个部分组成:

(1)操作系统用来管理线程的内核对象。内核对象也是系统用来存放线程统计信息的地方。
(2)另一个是线程的堆栈。它用于维护线程在执行代码时需要的所有函数的参数的局部变量。

线程是在它的进程地址空间中执行代码的,并且在地址的进程空间中对数据进行操作。

线程分为用户界面线程和工作线程。

1、线程与进程的比较

多进程是指在操作系统中能同时运行多个任务程序。

(1)进程的特点是允许计算机同时运行两个或更多的程序。

(2)在基于线程的多任务处理环境中,线程是最小的处理单位。

(3)多个进程的内部数据和状态都是完全独立的,而多线程共享一块内存空间和一组系统资源,有可能互相影响。

(4)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程的切换负担要小。

二、C# 中多线程的开发

1、线程操作

System.Threading.Thread

表-Thread 类的常用属性

属性名描述
CurrentThread只读属性,获取当前正在运行的线程
IsAlive判断线程是否处于活动状态
IsBackground获取或设置一个值,该值指示某个线程是否为后台线程
IsThreadPoolThread获取一个值,该值指示线程是否属于托管线程池
Name获取或设置线程的名称
PriorityThreadPriority 枚举类型,代表线程的优先级,如:Normal、AboveNormal、BelowNormal、Highest、Lowest
ThreadStateThreadState 枚举类型,代表当前线程的状态,如:Unstarted、Running、WaitSleepJoin、Stopped、AbortRequested、Susppended、Aborted 等

表-Thread 类的常用方法

方法名描述
GetDomain()返回当前线程所在的应用程序域
GetDomainID()返回当前线程所在的应用程序域的 ID
Start()启动线程的执行
Suspend()挂起线程,或者如果线程已挂起,则不起作用
Resume()继续已挂起的线程
Interrupt()终止处于 Wait 或者 Sleep 或者 Join 线程状态的线程
Join()阻塞调用线程,直到某个线程终止时为止
Sleep()将当前线程阻塞指定的毫秒数
Abort()终止一个线程的运行。如果线程已经终止,则不能通过 Thrread.Start() 来启动线程

2、线程的控制操作

(1)创建线程

static void Main(string[] args){Thread t1 = new Thread(new ThreadStart(Thread1));//创建线程t1.Start();//启动线程Console.ReadKey();}public static void Thread1(){Console.WriteLine("This is a Thread test!");}

(2) 启动线程

t1.Start();

(3)休眠线程

线程的休眠是让当前的线程进入一定时间的休眠状态,时间一到线程将继续执行。

Thread.Sleep(1000);//线程休眠 1000 毫秒
TimeSpan WaitTime = new TimeSpan(0,0,0,0,1000);
Thread.Sleep(WaitTime);//线程休眠按天 小时 分钟 秒 毫秒计

(4)挂起线程

线程的挂起是暂停线程,如果不再启动线程,它将永远保持暂停状态。

if(t1.ThreadState == ThreadState.Running)//判断线程是否正在运行t1.Suspend();

(5)继续线程

已经挂起的线程可以使用 Thread 类的 Resume 方法继续运行。

if(t1.ThreadState == ThreadState.Suspended)//判断线程是否已被挂起t1.Resume();

(6)终止线程

if(t1.IsAlive)//判断线程是否处于活动状态t1.Abort();

3、线程同步

要求一个线程对共享资源访问完全结束后,再让另一个线程访问该资源,必须保证一个共享资源一次只能被一个线程使用。

(1)加锁(Lock)

lock(expression) statement_block

expression: 加锁的对象,必须是引用类型。如果是类的实例,使用 this。如果保护一个静态成员,格式为:lock(typeof(类名)){ }

statement_block: 代表共享资源,在一个时刻内只能被一个线程执行。

(2)监视器(Monitor)

Monitor 类是一个静态类。Monitor 类通过使用 Enter 方法向单个线程授予获取锁定对象的钥匙来控制对对象的访问,该钥匙提供限制访问代码块(通常称为临界区,由 Monitor 类的 Enter 方法标记临界区的开头,Exit 方法标记临界区的结尾)的功能。当一个线程拥有对象的钥匙时,其他任何线程都不能获取该钥匙。

表-Monitor 类的常用方法

方法名描述
Enter()获取锁定对象的钥匙,同时标记临界区的开头。如果此时正有另外一个线程掌管这把钥匙,该方法将进入阻塞状态,直到锁定的对象被打开,如果同一线程正掌管钥匙,再次调用 Enter 方法将不会阻塞
TryEnter()和 Enter 方法类似,不同的是,当对象正被其他线程使用时,该方法不会自动阻塞,而是返回一个 false 值表明失败
Exit()结束对一个对象的监视,即交出锁定对象的钥匙,同时标记受锁定对象保护的临界区的结尾
Pulse()该方法通知位于等待队列中的下一个线程进入就绪队列,一旦调用该方法的线程释放钥匙后,就绪队列的线程就可以获取钥匙
PulseAll()和 Pulse 方法相似,通知等待队列中的所有线程转移到就绪队列中
Wait()释放对象的锁,并阻止当前线程直到它重新获取该锁

(3)互斥体(Mutex)

互斥体是通过只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。

表-Mutex 类的构造函数及方法重载说明

函数原型描述
public Mutex()调用此构造函数相当于带哦用构造函数 public Mutex(false),将互斥体的初始所属权指定为 false,即调用线程不拥有互斥体所有权
public Mutex(bool initiallyOwned)如果 initiallyOwned 为 false,则使用情况同上,如果为 true,则表示调用线程拥有互斥体的初始所有权
public Mutex(bool initiallyOwned, string name)第一个参数使用情况同上。第二个参数表示用字符串 name 作为该互斥体的名称来初始化 Mutex 类的新实例,如果 name 值为空引用,则 Mutex 是未命名的
public Mutex(bool initiallyOwned, string name, out bool createdNew)前两个参数同上。第三个参数是用来在该方法返回时指示调用线程是否被授予了互斥体的初始所有权,如果调用线程被授予了互斥体的初始所有权,则方法返回时 createdNew 为 true,否则为 false
public Mutex(bool initiallyOwned, string name, out bool createdNew, MutexSecurity mutexSecurity)前三个参数同上。第四个参数用于指示该已命名的互斥体的访问控制安全性
public virtual bool WaitOne()用于请求互斥体的所有权
public virtual bool WaitOne(TimeSpan timeout, bool exitContex) 、public virtual bool WaitOne(int milliseconds Timeout, bool exitContex)第一个参数用于指定等待时间,如果超过等待时间线程还没有获取互斥体,WaitOne 方法将返回 false。第二个参数用来指定在开始等待之前,是否先退出调用上下文所在的同步域(如果处于同步上下文中),exitContext 为 true,则等待之前先退出上下文的同步域,否则为 false
public bool ReleasedMutex()用于释放已经拥有的互斥体

三、多线程示例

模拟一家人削苹果和吃苹果的实例。

生产者: 爸爸妈妈作为生产者,不断削苹果往盘子里放。
消费者: 有三个孩子。老大、老二、老三不断从盘子里取苹果吃。
盘子: 盘子数,可放苹果总数,有从盘子里存放和取出苹果的功能。

1)定义盘子(Dish)

使用到 lock (this)、Monitor.Wait(this)、Monitor.PulseAll(this)、Thread.CurrentThread.Abort()

 class Dish{int f = 5;//盘子最多只能放5个苹果EatAppleSmp oEAP;int EnabledNum;//可放苹果总数int n = 0;public Dish(EatAppleSmp oEAP, int EnabledNum){this.oEAP = oEAP;this.EnabledNum = EnabledNum;}//放苹果public void put(string name){lock (this)//苹果已满,线程等待{while (f == 0)//苹果已满,线程等待{try{System.Console.WriteLine(name + "正在等待放入苹果");Monitor.Wait(this);}catch (ThreadInterruptedException) { }}f = f - 1;//削完一个苹果放一次n = n + 1;System.Console.WriteLine(name + "放1个苹果");Monitor.PulseAll(this);if (n > EnabledNum)Thread.CurrentThread.Abort();}}//取苹果public void get(string name){lock (this)//同步控制取苹果{while (f == 5){try{System.Console.WriteLine(name + "等待取苹果");Monitor.Wait(this);}catch (ThreadInterruptedException) { }}f = f + 1;System.Console.WriteLine(name + "取苹果吃...");Monitor.PulseAll(this);}}}

2)定义生产者(Productor)

使用到 Thread.Sleep()

  //生产者class Productor{private Dish dish;private string name;public Productor(string name, Dish dish){this.name = name;this.dish = dish;}public void run(){while (true){dish.put(name);try{Thread.Sleep(600);//削苹果时间}catch (ThreadInterruptedException) { }}}}

3)定义消费者(Consumer)

使用到 Thread.Sleep()

 //消费者class Consumer{private string name;private Dish dish;private int timelong;public Consumer(string name, Dish dish, int timelong){this.name = name;this.dish = dish;this.timelong = timelong;}public void run(){while (true){dish.get(name);try{Thread.Sleep(timelong);//吃苹果时间}catch (ThreadInterruptedException) { }}}}

4) 开启线程,执行削苹果和取苹果的功能

class EatAppleSmp{public EatAppleSmp(){Thread th_mother, th_father, th_young, th_middle, th_old;Dish dish = new Dish(this, 30);//生产者Productor mother = new Productor("妈妈", dish);Productor father = new Productor("爸爸", dish);//消费者Consumer old = new Consumer("老大", dish, 1000);Consumer middle = new Consumer("老二", dish, 1000);Consumer young = new Consumer("老三", dish, 1000);//建立线程th_mother = new Thread(new ThreadStart(mother.run));th_father = new Thread(new ThreadStart(father.run));th_old = new Thread(new ThreadStart(old.run));th_middle = new Thread(new ThreadStart(middle.run));th_young = new Thread(new ThreadStart(young.run));th_mother.Priority = ThreadPriority.Highest;//设置优先级th_father.Priority = ThreadPriority.Normal;th_old.Priority = ThreadPriority.Lowest;th_middle.Priority = ThreadPriority.Normal;th_young.Priority = ThreadPriority.Highest;th_mother.Start();th_father.Start();th_old.Start();th_middle.Start();th_young.Start();}}

5) 在主线程里执行

class Program{static void Main(string[] args){EatAppleSmp mainstart = new EatAppleSmp();Console.ReadKey();}}

输出结果:

妈妈放1个苹果
爸爸放1个苹果
老三取苹果吃...
老二取苹果吃...
老大等待取苹果
妈妈放1个苹果
爸爸放1个苹果
老大取苹果吃...
老二取苹果吃...
老三等待取苹果
妈妈放1个苹果
老三取苹果吃...
爸爸放1个苹果
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老大取苹果吃...
爸爸放1个苹果
妈妈放1个苹果
老二取苹果吃...
老三取苹果吃...
爸爸放1个苹果
妈妈放1个苹果
老大取苹果吃...
爸爸放1个苹果
妈妈放1个苹果
老二取苹果吃...
老三取苹果吃...
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老大取苹果吃...
妈妈放1个苹果
爸爸放1个苹果
老二取苹果吃...
老三取苹果吃...
老大取苹果吃...
老二取苹果吃...
老三取苹果吃...
老大等待取苹果
老二等待取苹果
老三等待取苹果

http://www.ppmy.cn/news/582859.html

相关文章

【三维编辑】Editing Conditional Radiance Fields 编辑条件辐射场

Editing Conditional Radiance Fields(ICCV 2021) 作者单位:Steven Liu, Xiuming Zhang, Zhoutong Zhang, Richard Zhang MIT, Adobe Research, CMU 代码地址:https://github.com/stevliu/editnerf 文章目录 摘要前言一、相关工作…

综合使用各类方法,彻底关闭win10自动更新

目录 一:禁用window update服务 二:在策略中关闭win10自动更新的相关设置 三:任务计划内的Win10更新 四:在注册表中关闭Win10自动更新 结果: 另一种针对注册表的方法: 各个网站文章,作者找了很久…

windows7 使用激活工具激活系统出现的问题汇总

1.激活后卡在logo界面一动不动。 在网上查询可能是因为无法正常读取硬盘导致的。可以将硬盘线拔开,之后进入BIOS界面恢复初始设置,之后再重新插好硬盘线即可正常开机。 2.激活后重新开机打开任何软件都提示缺失user32.dll。 这个可以在cmd中输入sfc /sca…

win7系统一键还原功能怎么进行禁用教学分享

win7系统一键还原功能怎么进行禁用教学分享。有的用户家里有小孩会使用电脑,担心自己的电脑被小孩进行了一键还原,造成数据的丢失,所以想要去进行改功能的禁用。那么如何去进行禁用的设置呢?一起来看看详细的操作方法教学吧。 操作…

Windows xp home edition 安装程序的产品密钥

Windows XP Home Edition 简体中文零售版原版 CD-KEY:BQJG2-2MJT7-H7F6K-XW98B-4HQRQ Windows XP Home Edition 简体中文OEM版 CD-KEY:JQ4T4-8VM63-6WFBK-KTT29-V8966

winrar5.31 专用激活key

RAR registration data 吾爱破解永久授权 Unlimited Company License UID5b2cd25a94422dbad9a7 6412212250d9a73974a519b3adc819906ee860f98a8344d5f8bf8f e7966653fd172bee328c60fce6cb5ffde62890079861be57638717 7131ced835ed65cc743d9777f2ea71a8e32c7e593cf66794343565 b4…

windows7激活文件备份

\Windows\System32\spp\tokens\pkeyconfig\pkeyconfig.xrm-ms \Windows\ServiceProfiles\NetworkService\AppData\Roaming\Microsoft\SoftwareProtectingPlatform\tokens.dat 1、备份以上两个文件,同时保存好激活CD-KEY(注意:appdata是隐藏的…

[win7] window 7 home basic - administrator帐号的激活

一般品牌机预装了win7,可几乎都是家庭版,所以很多功能都是受限制了. 比如win7旗舰版中,激活administrator帐号,只需如下操作即可完成: 控制面板-->管理工具-->计算机管理-->本地用户和组-->用户-->鼠标右键单击administrator选属性--〉将帐户已禁用的钩去掉--〉…

手动备份、还原windows7、office2010激活信息

(1)备份windows7激活信息 A:备份以下二个文件: 注意:appdata是隐藏的文件夹) appdata是隐藏的文件夹 C:/Windows/System32/spp/tokens/pkeyconfig/pkeyconfig.xrm-ms C:/Windows/ServiceProfiles/NetworkService/A…

windows7内部版本7601此副本不是正版 桌面背景黑屏

很多时候,我们装的系统都是盗版系统,而不是正版的。经常用的就是系统的副本,副本用一段时间后,就会提示不是正版,然后桌面的图标变黑。右下角会提示“ 此windows7副本不是正版”。有两种方式激活! 今天公…

别人修改夏普3.5寸TFT的经验

修改2410的3.5寸显示驱动遇到下半屏无图像的问题?我在调试2410 的TFT显示驱动时遇到一个始终解决不了的问题,即只能正常显示上半部屏幕,下班部分则只是点亮,没有图像。请求各位大侠慷慨帮助:) 5O(U1 * 我选…

win7黑屏怎么办?最后一批win7旗舰版珍藏版密钥。

win7黑屏是很多同学遇到过的最头痛的问题,今天小编就手把手教你解决windows7黑屏的问题,出现这种情况主要有以下两个原因: 一:您的windows7系统试用期已过。 二.您采取了微软不认可的激活方法。 首先您需要找到可用的windows7密钥&#xff0…

[转帖]惠普笔记本Win7激活方法

由于惠普笔记本主板的特殊性,让很多Win7激活工具无法使用。硬的不行,就来软的吧!虽然方法有点傻瓜式,也有点无奈,但总比激活不了黑屏的好吧!想试的就看看以下文章!win7 激活步骤1:首…

C语言中的错误类型有哪些?如何处理错误?

在C语言中,错误类型主要分为语法错误和运行时错误两种。 语法错误是指在编写代码时,程序员使用了不符合语法规则的语句或表达式,导致编译器无法正确解析代码。这种错误通常会在编译时被发现,编译器会输出相应的错误信息&#xff…

15.OCR

15.1 OCR流水线及七工作原理 Photo OCR:照片 光学字符识别(photo optical character recognition) Photo OCR注重的问题:如何让计算机都出图片中的文字信息,它有以下步骤: 首先给定某张图片,它将图像扫描一遍&#…

Sangfor华东天勇战队:mybatis-plus demo

基本依赖添加&#xff0c;表创建&#xff0c;启动类&#xff0c;测试类 引入依赖&#xff1a; <!-- mybatis-plus 依赖--> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version…

如何驯化机器狗读懂人类手势,手把手教你!

作为全国普通高校大学生竞赛榜单内竞赛&#xff0c;“中国软件杯”大学生软件设计大赛-智能四足机器狗电力巡检系统开发赛项&#xff0c;目前已吸引了全国2041支队伍参加。经过激烈的目标检测与分割算法打榜赛&#xff0c;最终&#xff0c;有153支团队成功晋级区域赛。在即将于…

阿里旺旺 v10.00.08C 官方版

https://wangwang.taobao.com/ 没搞明白&#xff0c;阿里官网竟然没放最新的版本 实际上&#xff0c;阿里放了至少2组地址可以下载&#xff1a; https://download.alicdn.com/wangwang/AliIM_taobao_(9.12.10C).exe https://download.alicdn.com/wangwang/AliIM_taobao_(10.00…

去广告版阿里旺旺

官方原版的真垃圾&#xff0c;聊天窗口闪啊闪&#xff0c;聊天窗口无法关闭&#xff0c;无法打字&#xff0c;无法切换聊天。他内部好像一直在刷广告&#xff0c;但是一直失败&#xff0c;然后不停尝试&#xff0c;真是弱智。 果断换了个去广告版&#xff0c;在吾爱下载找的。…
最新文章