目录
- 一、概念
- 二、原理
- 硬件结构
- 运行时
- 三、基础
- 创建与启动
- 传递参数
- 前台/后台线程
- 异常处理
- 中断与中止
- 中断(Interrupt)
- 中止(Abort)
- 协作取消模式
- 四、异步编程模式
- 异步编程模型(APM)
- 基于事件的异步模式(EAP)
- 基于任务的异步模式 (TAP)
- 五、拓展知识
- 线程优先级
- 什么是进程退出?
- windows中通过任务管理器,linux中通过kill去杀掉一个进程,其资源是否会释放?
《Threading in C# 》中文翻译(GKarch ):https://blog.gkarch.com/topic/threading.html
《图解系统》(小林coding):https://xiaolincoding.com/os/
并行(parallel):同一时间,多个线程/进程同时执行 。多线程的目的就是为了并行 , 充分利用cpu多个核心,提高程序性能
线程(threading):线程是操作系统能够进行 运算调度的最小单位,是进程的实际运作单位 。一条线程指的是进程中一个单一顺序的控制流 , 一个进程中可以并行多个线程,每条线程并行执行不同的任务 。
进程(process):进程是操作系统进行资源分配的基本单位 。多个进程并行的在计算机上执行,多个线程并行的在进程中执行,进程之间是隔离的,线程之间共享堆,私有栈空间 。
CLR 为每个线程分配各自独立的 栈(stack) 空间 , 因此局部变量是线程独立的 。
static void Main(){new Thread(Go).Start();// 在新线程执行Go()Go();// 在主线程执行Go()}static void Go(){// 定义和使用局部变量 - 'cycles'for (int cycles = 0; cycles < 5; cycles++) Console.Write ('?');}
变量cycles的副本是分别在线程各自的栈中创建,因此会输出 10 个问号??????????
线程可以通过对同一对象的引用来共享数据 。例如:static bool done = false;static void Main(){new Thread (tt.Go).Start(); // AGo(); // B}static void Go(){if (!done) {Console.WriteLine ("Done");done = true;}}
这个例子引出了一个关键概念 线程安全(thread safety) , 由于并发 , ” Done “ 有可能会被打印两次通过简单的加锁操作:在读写公共字段时,获得一个 排它锁(互斥锁,exclusive lock ) ,c#中使用lock即可生成 临界区(critical section)
static readonly object locker = new object();...static void Go(){lock (locker) // B{if (!done) {Console.WriteLine ("Done");done = true;}}}
临界区(critical section):在同一时刻只有一个线程能进入,不允许并发 。当有线程进入临界区段时,其他试图进入的线程或是进程必须 等待或阻塞(blocking)线程阻塞(blocking):指一个线程在执行过程中暂停,以等待某个条件的触发来解除暂停 。阻塞状态的线程不会消耗CPU资源
挂起(Suspend):和阻塞非常相似 , 在虚拟内存管理的操作系统中 , 通常会把阻塞状态的进程的物理内存空间换出到硬盘,等需要再次运行的时候,再从硬盘换入到物理内存 。描述进程没有占用实际的物理内存空间的情况,这个状态就是挂起状态 。
可以通过调用Join方法等待线程执行结束 , 例如:
static void Main(){Thread t = new Thread(Go);t.Start();t.Join();// 等待线程 t 执行完毕Console.WriteLine ("Thread t has ended!");}static void Go(){for (int i = 0; i < 1000; i++) Console.Write ("y");}
也可以使用Sleep使当前线程阻塞一段时间:Thread.Sleep (500);// 阻塞 500 毫秒
Thread.Sleep(0)会立即释放当前的时间片(time slice),将 CPU 资源出让给其它线程 。Framework 4.0的Thread.Yield()方法与其大致相同 , 不同的是Yield()只会出让给运行在相同处理器核心上的其它线程 。二、原理硬件结构https://xiaolincoding.com/os/1_hardware/how_cpu_run.html#图灵机的工作方式
Sleep(0)和Yield在调整代码性能时偶尔有用 , 它也是一个很好的诊断工具,可以用于找出线程安全(thread safety)的问题 。如果在你代码的任意位置插入Thread.Yield()会影响到程序 , 基本可以确定存在 bug 。
运行时??线程在内部由一个 线程调度器(thread scheduler) 管理,一般 CLR 会把这个任务交给操作系统完成 。线程调度器确保所有活动的线程能够分配到适当的执行时间,并且保证那些处于等待或阻塞状态(例如,等待排它锁或者用户输入)的线程不消耗CPU时间 。
推荐阅读
- 云原生之旅 - 11)基于 Kubernetes 动态伸缩 Jenkins Build Agents
- go GMP
- iphone13出来12会降价吗_iphone13出来12能便宜多少
- 苹果13mini屏幕多大尺寸_苹果13mini屏幕尺寸
- 618红米k40pro会降价吗_618红米k40pro能便宜多少
- 我的世界漏斗与漏斗之间怎么相连(我的世界漏斗上怎么放东西)
- 洛谷 P4135 作诗 题解
- 明日方舟泳装皮肤多少源石头
- 电脑垫多高颈椎最舒服_显示器抬高多少厘米合适
- iqoo7支持无线充电吗_iqoo7电池容量是多少