C#学习笔记-异步编程(1):多线程
进程和线程
-
进程:给定程序当前正在执行的实例(P506)【比如Word,每打开编辑一个Word文档都是一个独立的实例,相互之间隔离、不共享数据】
-
线程:程序“控制点”(P506)【比如网易云音乐,播放音乐的同时,还可以查看歌曲评论、同时歌词还在滚动展示,每个功能都是这个软件一个控制点的延续】
多线程主要用于解决两类问题
-
实现多任务
-
解决延迟
计算延迟与多线程/进程
计算机执行时有两类造成计算延迟的类型:
-
CPU密集型/计算密集型:大部份时间用来做计算、逻辑判断等CPU 动作的程序称之CPU 密集型。
-
I/O密集型:系统运作,大部分的状况是CPU 在等I/O (硬盘/内存)的读/写。
多进程适合在CPU 密集型操作(CPU操作指令比较多,如位数多的浮点运算)。多线程适合在IO 密集型操作(读写数据操作较多的,比如爬虫)。
并发/并行
-
并行:“一起”进行的操作【例如在喝水的时候,眼睛盯着电脑屏幕看文档、耳朵听着音乐、手上还在记笔记。用造句就是一边做A,一边做B,一会儿做C】
-
并发:几个操作在一段时间内容同时被完成,一个操作完成的同时、顺带另一个任务也被完成【炒菜的时候,天下雨了,去阳台收衣服的同时,还要时不时地回厨房看下菜有没有糊。用造句就是一会儿做A,一会儿做B,一会儿做C】。
【注:相比于并行,并发其实有个隐藏的前提,就是可供调度的资源数是有限的。如果我可以分身,那么一个我去收衣服,另一个我在炒菜,就不构成并发的场景。同样的,之所以我可以并行做多件事,只是相对于我这个大系统而言,若是要我喝水的时候说话,我也做不到,因为嘴巴这个资源是有限的,只能喝口水之后再讲话。】
并发/并行与多线程/进程
-
并行可以通过多进程实现。可以看到并行其实暗示着各个操作相互之间是隔离的,通过分配到多个进程则可以实现这个目的。
-
并发可以通过多线程实现。前面提到并发的前提,对于单个计算机而言,就是任务数多、CPU核数少的场景。因此只能通过调度多个线程、所有线程共享有限的内存空间来实现。
多线程的实现方式
类似于前面的例子,操作系统和人一样,也是通过“一会儿做A,一会儿做B”来实现多线程的。具体方式就是“时间切片(time slicing)”的机制来模拟多个线程并发运行。操作系统以极快的速度从一个线程切换道另一个线程,给人的感觉就是所有线程都在同时执行。(P507)
多线程的问题
-
上下文切换【即时间切片】是有代价的,线程太多,切换开销就会开始显著影响性能。(P507)
-
【非原子性操作触发竞态条件,造成不确定性】。当两个线程访问同一对象时,操作系统会在它认为合适的任何时间,在任何两个线程之间切换上下文,无法预测哪个“线程”会抢先运行。而部分完成的非原子性操作就会造成【数据的】不一致状态。(P508)
-
【缓存与主存同步的定时性使得数据不一致】。缓存会定时与主内存同步,两个线程分别处理读写各自从主存中同步的缓存数据,相互之间看不到对方的时时更新,造成结果不一致。(P508)
-
锁定造成死锁。两个线程相互等待对方释放锁才能运行,结果造成了程序锁死。(P509)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义