《操作系统导论》第26章读书笔记:并发:介绍

《操作系统导论》第26章读书笔记:并发:介绍

------ 杭州 2024-04-18 夜

文章目录

0.前言

  • 多线程(multi-threaded):程序会有多个执行点(多个程序计数器,每个都用于取指令和执行)。
  • 换一个角度来看,每个线程类似于独立的进程,只有一点区别:他们共享地址空间,从而能够访问相同的数据。
  • 单个线程的状态与进程状态非常类似。
  • 每个线程有自己的一组用于计算的寄存器。
  • 上下文切换(context switch)、进程控制块(Process Control Block,PCB)
  • 与进程相比,线程之间的上下文切换有一点主要区别:地址空间保持不变。(即不需要切换当前使用的页表)
  • 另一个主要区别:在简单的传统进程地址空间模型 [我们现在可以称之为单线程(single-threaded)进程] 中,只有一个栈,通常位于地址空间的底部。然而,在多线程的进程中,每个线程独立运行,当然可以调用各种例程来完成正在执行的任何工作。不是地址空间中只有一个栈,而是每个线程都有一个栈。
  • ,可以看到两个栈跨越了进程的地址空间。因此,所有位于栈上的变量、参数、返回值和其他放在栈上的东西,将被放置在有时称为线程本地(thread-local)存储的地方,即相关线程的栈。

1.实例:线程创建(略)

2.为什么更糟糕:共享数据(略)

3.核心问题:不可控的调度

  • 竞态条件(race condition):结果取决于代码的时间执行。
  • 临界区(critical section):由于执行这段代码的多个线程可能导致竞争状态,因此我们将此段代码称为临界区(critical section)。临界区是访问共享变量(或更一般地说,共享资源)的代码片段,一定不能由多个线程同时执行。
  • 互斥(mutual exclusion):这个属性保证了如果一个线程在临界区内执行,其他线程将被阻止进入临界区。

4.原子性愿望

  • 原子方式(atomically):硬件保证它以原子方式(atomically)执行。当指令执行时,它会像期望那样执行更新。它不能在指令中间中断,因为这正是我们从硬件获得的保证:发生中断时,指令根本没有运行,或者运行完成,没有中间状态。
  • 原子方式的意思是"作为一个单元",有时我们说"全部或没有"。
  • 我们要做的是要求硬件提供一些有用的指令,可以在这些指令上构建一个通用的集合,即所谓的同步原语(synchronization primitive)。通过使用这些硬件同步原语,加上操作系统的一些帮助,我们将能够构建多线程代码,以同步和受控的方式访问临界区,从而可靠地产生正确的结果------ 尽管有并发执行的挑战。
  • 临界区(critical section):是访问共享资源的一段代码,资源通常是一个变量或数据结构。
  • 竞态条件(race condition):出现在多个执行线程大致同时进入临界区时,它们都试图更新共享的数据结构,导致了令人惊讶的(也许是不希望的)结果。
  • 不确定性(indeterminate):程序由一个或多个竞态条件组成,程序的输出因运行而异,具体取决于哪些线程在何时运行。这导致结果不是确定的(deterministic),而我们通常期望计算机系统给出确定的结果。
  • 互斥(mutual exclusion)原语:为了避免这些问题,线程应该使用某种互斥(mutual exclusion)原语。这样做可以保证只有一个线程进入临界区,从而避免出现竞态,并产生确定的程序输出。

5.还有一个问题:等待另一个线程

  • 两种交互:
    • 第一种交互------访问共享变量:因此需要为临界区支持原子性。
    • 第二种交互------睡眠/唤醒交互的机制:即一个线程在继续之前必须等待另一个线程完成某些操作。例如,当进程执行磁盘I/O 并进入睡眠状态时,会产生这种交互。当I/O 完成时,该进程需要从睡眠中唤醒,以便继续进行。
  • 条件变量(condition variable)。
  • 将一系列动作原子化(atomic)背后的想法可以简单用一个短语表达:"全部或没有"。看上去,要么你希望组合在一起的所有活动都发生了,要么它们都没有发生。不会看到中间状态。有时,将许多行为组合为单个原子动作称为事务(transaction),这是一个在数据库和事务处理世界中非常详细地发展的概念。
相关推荐
亽仒凣凣4 分钟前
Windows安装Redis图文教程
数据库·windows·redis
ELI_He9996 分钟前
PHP中替换某个包或某个类
开发语言·php
m0_7482361114 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
倔强的石头10622 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
ProtonBase25 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
Watermelo61726 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v32 分钟前
leetCode43.字符串相乘
java·数据结构·算法
希忘auto2 小时前
详解Redis的常用命令
redis·1024程序员节
半盏茶香2 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J3 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab