【OSTEP】并发:线程与多线程

2024-04-05 05:44
文章标签 线程 并发 多线程 ostep

本文主要是介绍【OSTEP】并发:线程与多线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

" A flow of control within a process that consists of a PC, a register set and a stack space"

 本章将介绍为单个运行进程提供的新抽象 —— 线程 (thread) 

  • 线程是 \textrm{CPU} 调度的一个基本单位(basic unit of CPU scheduling)
  • 一个单独的线程至少有自己的寄存器状态,通常还有自己的栈。

" 在同一进程中可以创建多个线程,并共享代码、地址空间和进程的操作资源 "

❓ 思考:那么问题来了,线程和多线程的区别是什么?

这里有一个经典观点就是:一个程序只有一个执行点,但多线程有多个执行点。

 就让荀彧 (不是苟或!!!) 来给大家举个栗子:

  • 线程:一个程序计数器,用来存放要执行的指令。
  • 多线程:多个程序计数器,每个都用于取指令和执行。

多线程每个线程都类似于独立的线程,所以没有什么太大的区别,它们只有一点区别 ——

 (线程之间共享地址空间,从而能够访问相同的数据)

💡 区别:多线程 共享 地址空间  。因此,单个线程的状态与进程状态非常类似。

线程有一个程序计数器(\textrm{PC}),用于记录程序从哪里获取指令。

 每个线程都有自己的一组用于计算的寄存器,没错就是这么牛啤,人手一套的那种。

所以,如果有两个线程运行在同一处理器上,从运行一个线程 T1 切换到另一个线程 T2 时:

必定会发生 上下文切换 (context switch),我们讲过进程的上下文切换,它是通过 PCB 解决的。 

而线程的上下文切换也是类似于进程的上下文切换的,线程是通过 TCB 解决的。

  • 对于进程:我们将状态保存到进程控制块(PCB )
  • 对于线程:我们要保存每个线程的状态,就需要一个或多个线程控制块(TCB

 但是!与进程相比,线程的上下文切换有 "一点" 不同!

🔍 主要区别:线程的上下文切换,地址空间保持不变(这意味着不需要切换当前使用的页表)。

  • 当 T1\rightarrow T2 时,T1 的寄存器状态被保存,T2 的寄存器状态被恢复,地址空间保持不变。
  • 线程的创建和切换成本是很低的,非常的便宜,因为它们只需要一个栈和存储寄存器。

在多个线程中,每个线程独立运行,不是地址空间中只有一个栈,而是每个线程都有一个栈。

💭 假设:有一个多线程的进程,它有两个线程,结果地址空间看起来不同:

  • 从图中可以观察到,两个栈跨越了进程的地址空间,因此所有位于栈上的变量、参数、返回值和其他能放在栈上的东西,将被放置在线程本地 (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/.

这篇关于【OSTEP】并发:线程与多线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877754

相关文章

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线