" A flow of control within a process that consists of a PC, a register set and a stack space"
本章将介绍为单个运行进程提供的新抽象 —— 线程 (thread)
- 线程是 调度的一个基本单位(basic unit of CPU scheduling)
- 一个单独的线程至少有自己的寄存器状态,通常还有自己的栈。
" 在同一进程中可以创建多个线程,并共享代码、地址空间和进程的操作资源 "
❓ 思考:那么问题来了,线程和多线程的区别是什么?
这里有一个经典观点就是:一个程序只有一个执行点,但多线程有多个执行点。
就让荀彧 (不是苟或!!!) 来给大家举个栗子:
- 线程:一个程序计数器,用来存放要执行的指令。
- 多线程:多个程序计数器,每个都用于取指令和执行。
多线程每个线程都类似于独立的线程,所以没有什么太大的区别,它们只有一点区别 ——
(线程之间共享地址空间,从而能够访问相同的数据)
💡 区别:多线程 共享 地址空间 。因此,单个线程的状态与进程状态非常类似。
线程有一个程序计数器(),用于记录程序从哪里获取指令。
每个线程都有自己的一组用于计算的寄存器,没错就是这么牛啤,人手一套的那种。
所以,如果有两个线程运行在同一处理器上,从运行一个线程 切换到另一个线程 时:
必定会发生 上下文切换 (context switch),我们讲过进程的上下文切换,它是通过 解决的。
而线程的上下文切换也是类似于进程的上下文切换的,线程是通过 解决的。
- 对于进程:我们将状态保存到进程控制块( )
- 对于线程:我们要保存每个线程的状态,就需要一个或多个线程控制块()
但是!与进程相比,线程的上下文切换有 "一点" 不同!
🔍 主要区别:线程的上下文切换,地址空间保持不变(这意味着不需要切换当前使用的页表)。
- 当 时, 的寄存器状态被保存, 的寄存器状态被恢复,地址空间保持不变。
- 线程的创建和切换成本是很低的,非常的便宜,因为它们只需要一个栈和存储寄存器。
在多个线程中,每个线程独立运行,不是地址空间中只有一个栈,而是每个线程都有一个栈。
💭 假设:有一个多线程的进程,它有两个线程,结果地址空间看起来不同:
- 从图中可以观察到,两个栈跨越了进程的地址空间,因此所有位于栈上的变量、参数、返回值和其他能放在栈上的东西,将被放置在线程本地 (thread-loacl) 存储的地方。
- 多个栈也破坏了地址空间布局的美感,以前,堆和栈可以互不影响的增长,直到空间耗尽。而现在多个栈就没有这么简单了,值得庆幸的是,通常栈不会很大(除非大量使用递归程序)。
为什么要用线程?为什么?因为快!
📌 [ 笔者 ] 王亦优
📃 [ 更新 ] 2022.
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!
📜 参考资料 Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces A. Silberschatz, P. Galvin, and G. Gagne, Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/. |