【笔记】南大操作系统jyy

文章预览:

b站视频链接:
操作系统概述 (为什么要学操作系统) 南京大学2022操作系统-蒋炎岩

说明:目前还没更新完,感觉这门课更注重实战,不只是讲ppt,会带着你写代码,如果想看操作系统具体概念的可以去看考研的课程

三 多处理器编程:从入门到放弃 (线程库;现代处理器和宽松内存模型)

1. 以状态机的观点看CPU执行,

共享: 全局的变量, 系统调用等库函数,

独占: 线程栈帧, thread_local 变量

2. 多线程对程序执行流 和 一些默认假设的改变

指令不再具有 原子性, 顺序性, 内存一致性

3. 现代处理器

指令执行

(顺序性也可能会在编译优化下消失)

单条汇编指令 也非原子的 

它将指令解释为 *μops*

内存模型

4.有一些不可能出现的结果出现了,可能是因为c语言在编译成汇编的时候使他保持串行,当时汇编再编译成更小单元时串行的部分被“优化”成并行了

5、状态机=create+join

join

线程C-线程联合join

yield

多线程之yield()方法

syscall

Linux 系统调用原理——syscall

四 理解并发程序执行 (Peterson算法、模型检验与软件自动化工具)

操作系统:设计与实现:

1️⃣Peterson 算法✔️

2️⃣正确性证明和压力测试✔️

3️⃣自动证明:模型检验✔️

一、Peterson 算法✔️

✨互斥:保证两个线程不能同时执行一段代码。

插入“神秘代码”,使得sum.c(或者任意其他代码)能够正常工作

假设一个内存的读/写可以保证顺序、原子完成

00:00
Peterson 算法

二、正确性证明和压力测试✔️

✨进入临界区的情况

如果只有一个人举旗,他就可以直接进入

如果两个人同时举旗,由厕所门上的标签决定谁进

手快囿(被另一个人的标签覆盖)、手慢黑

一些具体的细节情况

·A看到B没有举旗.

B一定不在临界区

或者B想进但还没来得及把“A正在使用”贴在门上

memory ordering

A看到B举旗子

A一定已经把旗子举起来了
在这里插入图片描述

27:13
正确性证明和压力测试

三、自动证明:模型检验✔️

并发算法的设计困境

不敢不画:谁知道有什么奇怪情况会发生

不敢乱画︰画错了就都完了

解决困境

能不能让电脑帮我们画

有程序的形式语义(数学定义),就能写解释器模拟执行

54:59
自动证明:模型检验

五 并发控制:互斥 (自旋锁、互斥锁和 futex)

1、关于volatile

在这里插入图片描述

volatile

volatile详解(任何人都能懂的那种)

Linux C++】线程安全-原子性、可见性、有序性

【Linux C++】线程安全-原子性、可见性、有序性

六 并发控制:同步 (条件变量、信号量、生产者-消费者和哲♂学家吃饭问题)

1、assert断言函数

assert断言函数简介

2、信号量和条件量

linux条件变量使用和与信号量的区别

3、总结

在这里插入图片描述

七 真实世界的并发编程 (高性能计算/数据中心/人机交互中的并发编程)

1、线程的好处:可以使用多处理器

在这里插入图片描述
比如一个线程里面有很多个协程,协程A去请求数据时,其他协程都不能动,会浪费cpu资源
协程开销小,但是会有blocking的问题

线程和协程都不完美,解决方法如下:
在这里插入图片描述
每个cpu上都有一个线程,每个线程还有多个协程,减少了cpu的切换时间。
只要go程序在运行,总是会运行协程
协程如果想要执行耗时的操作,才会马上切换到另一个协程上去运行

2、同步和异步

一般我们对同步的理解是同时做很多事情,但程序中的同步是按照任务的顺序执行任务,前一个任务没有执行结束,下一个任务不会执行,要等待上一个任务执行结束。

异步:是同一时间内可以做多件事,这往往伴随着多线程

同步和异步主要的优缺点:
1、同步的执行效率会比较低,耗费时间,但有利于我们对流程进行控制,避免很多不可掌控的意外情况;
2、异步的执行效率高,节省时间,但是会占用更多的资源,也不利于我们对进程进行控制

3、并发、并行、串行、同步、异步的区别?

1.并发编程又叫多线程编程。
    在程序中,往往有很多很耗时的工作,比如上传文件、下载文件、跟客户聊天需要长时间建立连接。这种时候,一个线程是服务不了多个用户的,会产生因为资源独占产生的等待问题。并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间的多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率(买票问题并发进行)。
    并发当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

2.“并行”指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。(hadoop集群就是并行计算的)
    当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

并发和并行
    并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行。

3.串行、并行:
    并行和串行指的是任务的执行方式。串行是指多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个。并行指的是多个任务可以同时执行,异步是多个任务并行的前提条件。

4.同步、异步:
    指的是能否开启新的线程。同步不能开启新的线程,异步可以。
    异步:异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。
    异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或则交给另外的进程来处理。

5.多线程
    多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码。多线程可以实现线程间的切换执行

八 并发 bug 和应对 (死锁/数据竞争/原子性违反;防御性编程和动态分析)

1、CSAPP里面讲过的金丝雀也是属于防御性编程

2、并发bug:死锁和数据竞争

十 状态机模型的应用 (细胞自动机; gdb/rr/perf; 代码验证工具)

1、prifiler工具

2、使用150行的model checker来检查程序的并发性,不是并发性程序也可以检查

在这里插入图片描述
也可以对状态进行合并
在这里插入图片描述
在这里插入图片描述

3、状态机模型是个非常重要的工具,可以用它来查看过去和未来

十一 操作系统上的进程 (最小 Linux; fork, execve 和 exit)

1、通过fork来创建进程,fork是一条系统调用

程序就是状态机
操作系统在完成了启动之后实际上是创建了一个代表init的状态机
在这里插入图片描述
在操作系统代码执行完fork以后,系统里面会有两个完全一样的进程的副本

这些副本的内存的每个字节都一样,寄存器也一样,fork的返回值不一样
返回值eax寄存器,eax不一样
在这里插入图片描述
在这里插入图片描述
创建完状态机之后就会变成一个并发程序
操作系统就是一个管理者,去指挥下一步该干什么
在这里插入图片描述
虚拟化就是操作系统可以管理多个状态机

2、 理解fork

在这里插入图片描述
一个输出6个Hello,另一个输出8个Hello

line buffer:看到\n就会把所有缓冲区的东西都用系统单位写出来
full buffer:写满4096个字节后才会输出
在这里插入图片描述
所以6和8其实是一个是当场执行n立即打印,一个是管道执行n也藏着不打
在这里插入图片描述

在这里插入图片描述
就是相当于这几个进程的缓冲区是同一个,printf只是写入缓冲区但不打印?

下面这个例子会产生4个fork,首先父进程会创建子进程1和子进程2,子进程1又会执行第二个fork语句,所以子进程1又会再创建一个子进程。
在这里插入图片描述

下面这个例子不止会产生5个子进程,子进程1又会从i=1、2、3、4执行循环,子进程1产生的子进程又会产生子进程
在这里插入图片描述

3、execue:重置一个状态机,重置到某一个程序的初始状态

在这里插入图片描述

总结:fork相当于创建状态机,excue相当于更换状态机

4、exit

在这里插入图片描述
在这里插入图片描述

linux的exit和_exit

在这里插入图片描述

在linux的标准库函数中,有一套称作高级I/O的函数,我们熟知的printf 、fopen 、fread 、fwrite都在此列,他们也被称作缓冲I/O。其特征是对应每一个打开的文件,都存在一个缓冲区, 在内存中都有一片缓冲区,每次读文件会多读若干条记录,这样下次读文件时就可以直接从内存的缓存中取出,每次写文件时也仅仅是写入到内存的缓冲区,等待满足一定的条件(达到一定的数量,或者遇到特定字符,如换行和文件结束符EOF),再将缓冲区的内容一次性的写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦,如果有些数据,我们认为已经写入了文件,实际上因为没有满足特定的条件,他们还只是保存在缓冲区内,这时我们用_exit函数直接将程序关闭,缓冲区中的数据就会丢失,反之,如果向保证数据的完整性,就一定要使用exit函数。

第一个例子中输出ok语句是因为带了\n,会直接输出,并不会保存到缓冲区里面,而good语句是保存到缓冲区了,所以执行_exit时并不会输出,会直接退出

在这里插入图片描述

十二 进程的地址空间 (pmap; vdso; mmap; 游戏修改器/外挂)

1、linux命令行工具:fish

2、pmap可以查看进程的地址空间

利用man 5 proc可以查看手册

3、Linux 的 cat 命令各种用法

Linux 的 cat 命令各种用法

4、Linux学习之vim命令

Linux学习之vim命令

5、又想进行系统调用但是不想进入内核可以使用RTFM

在这里插入图片描述

6、vdso

通过vdso的官方手册可了解到,这是一个虚拟的共享库,由内核在应用运行时动态地加载,且其符号解析是由C语言动态库完成的。官方手册中给出了该共享库提供了哪些系统调用的替代函数(这样就解决了其中一个疑惑:除了vdso提供的系统调用,strace应当能捕捉到所有其他的系统调用),并说明这些被替代的函数具有高性能的特点,主要动机是提升应用的运行效率。

虚拟动态共享库VDSO的实现机制

可以实现不进入操作系统调用内核?

7、动态链接和静态链接

为什么要动态链接?
静态链接使得不同的程序开发者能够相对独立的开发和测试自己的程序模块,但是模块更新困难、浪费内存和磁盘空间等问题也凸显出来。

动态链接基本思想:对组成程序的目标文件等到程序运行的时候才进行链接,也就是说,把链接这个过程推迟到了运行时再进行,这就是动态链接的基本思想。
目前主流的操作系统都支持动态链接,在Linux系统中,ELF动态链接文件被称为动态共享文件(DSO,dynamic shared objects),简称共享对象,一般以.so结尾。

全过程:把主程序进行虚拟内存映射、进入链接器的入口链接器执行重定位和其他操作、进入到主程序的入口执行程序。

此处有个地方需要进行认知:在静态链接时,整个程序最终只有一个可执行文件,他是一个不可以分割的整体,但是在动态链接下,一个程序被分成了若干个文件,有程序的主要部分,即可执行文件和程序所依赖的共享对象。很多时候我们也把这些部分称为模块,即动态链接下的可执行文件和共享对象都可以看做是程序的一个模块。

在这里插入图片描述

8、mmap

可以帮助在内存空间里面找到一段新的内存
在这里插入图片描述

在这里插入图片描述

9 进程隔离

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43050258/article/details/129504157