【jyy os 2024】并发

05-多处理器编程

共享内存推翻了“原子性”的假设,同时也出现了并发性的Bugs
同时由于并发性的出现,编译的很多优化是不能做的了

06-并发控制:互斥 (1) (Peterson 算法、原子操作、自旋锁)

互斥->控制并发的出现->那为什么还需要并发?->代码是有一部分没办法并发执行,有一部分可以并发执行的->实际的计算是可以并行的。我们可以用很少的时间(阻止并发),把计算任务分配出去,剩下的时间都是在做局部的计算,不涉及共享状态的改变
实现互斥:
1.stop the world->关闭中断->实现原子性;有些中断是不可以屏蔽的
关中断不是万能的。单处理器系统可以,但是多处理器系统不行
2.Peterson算法:
只能在单处理器系统上
要进入临界区:举起自己的旗子,将 写有对方名字的旗子贴在门上;
然后进入持续观察:对方是否举旗子,门上的名字->进入的条件:对方没有举旗子旗子或者是门上贴的是自己的名字;
从临界区出来之后:放下自己的旗子
3.原子操作:软件方面不好实现,让硬件来实现->原子指令,一小段时间的“stop the world”
自旋锁:为每一个重要的资源都设置一把锁,多个进程去争抢的时候只有一个进程可以把状态置换出来
假如说T1现在获得了锁,然后被中断了,后面T2、T3无法获得锁,就会一直试图获取锁。由于在用户程序中,我们无法关中断,所以在用户程序中实现自旋锁是一个容易浪费资源的行为。但是在实际中OS会关中断,使得这种状况不会出现。

07-并发控制:互斥 (2) (内核中的自旋锁、Read-Copy-Update、互斥锁和 futex)

每一个CPU里面都有一位表示,我要不要打开中断。关中断是关的本CPU的中断,其他CPU的不会被关掉。
内核中有很多只读的进程。->Rerad-copy-update->写时复制->每次创建一个全新的变量,然后把写的指针移过去->所以会有读写交错的时候,这个时候可能会有一部分人读到的是旧版本的数据,但是有一部分人读到的是新版本的数据->牺牲了读写一致性来实现并发
当所有CPU切换一次线程后,所有CPU都不会再访问旧版本,就可以回收旧版本了

08-调试理论与实践 (Fault, Error, Failure;调试一切)

摆正心态:1.机器永远是对的;2.未测代码永远是错的
调试为什么困难:
需求->设计->代码(fault/bug)->执行(error)->失败(failure,可观测)
我们只能观测到failure,即是可观测的结果错->调试理论:如果我们能判定任意程序状态的正确性,那么给定一个 failure,我们可以通过二分查找定位到第一个 error 的状态,此时的代码就是 fault (bug)->所以我们喜欢单步调试(gdb/printf)
大部分error和failure是比较接近,出错时可以使用perror打印日志
找不到问题的原因:出错原因报告不准确、程序执行的过程看不到->把状态机拆开->ssh/gcc/make

- `ssh`:使用 `-v` 选项检查日志
- `gcc`:使用 `-v` 选项打印各种过程
- `make`:使用 `-nB` 选项查看完整命令历史

- Profiler: `perf` - “采样” 状态机
- Trace: `strace` - 追踪系统调用

09-并发控制:同步 (1) (生产者-消费者、条件变量)

让每一个进程都自旋等到所有进程到达同步条件达成
线程有先后,先来先等待
经典同步问题:生产者-消费者问题

你可能感兴趣的:(READ,more,books,学习方法)