【2021/7/19更新】【梳理】简明操作系统原理 第九章 死锁与活锁(docx)

配套教材:
Operating Systems: Three Easy Pieces Remzi H. Arpaci-Dusseau Andrea C. Arpaci-Dusseau Peter Reiher
参考书目:
1、计算机操作系统(第4版) 汤小丹 梁红兵 哲凤屏 汤子瀛 编著 西安电子科技大学出版社

在线阅读:
http://pages.cs.wisc.edu/~remzi/OSTEP/
University of Wisconsin Madison 教授 Remzi Arpaci-Dusseau 认为课本应该是免费的
————————————————————————————————————————
这是专业必修课《操作系统原理》的复习指引。
需要掌握的概念在文档中以蓝色标识,并用可读性更好的字体显示 Linux 命令和代码。代码部分语法高亮。
文档下载地址:
链接:https://pan.baidu.com/s/1EXvxivDgRJXcp-Uz1h-9DA
提取码:0000

九 死锁与活锁

有学者研究了常见的开源软件中的并发过程的Bug,它们大部分是非死锁引起的:

在这一章,我们对并发中的错误进行一些稍微深入的讨论。

违反原子性(atomicity-violation)是并发过程中的一种常见Bug。示例:
线程1:

if(thd->proc_info){
fputs(thd->proc_info, …);
}
线程2:
thd->proc_info = nullptr;
相信你已经很容易举出问题发生的条件:如果线程1在判断分支条件后就被打断,转而执行线程2,那么proc_info就变成了空指针。再次切回线程1的时候,对空指针的解引用将报错。
解决方法很简单:在这些代码前后增加获得锁和释放锁的语句。修正后的代码在这里略去。线程2虽然只有单条赋值语句,但是也需要用锁来确保原子性。因为很多时候写操作是非原子的。如果写的过程被调度器打断,转由其它线程对共享资源进行写入,那么接下来被打断的线程继续写入时,刚才的线程所做的更改就丢失了。这很可能会引发严重问题。

多个线程错误的执行顺序也有概率引发严重问题。举例:
线程1:

void init() {
mThread = PR_CreateThread(mMain, …);
}
线程2:
void mMain(…) {
mState = mThread->State;
}
显然,线程2应该在线程1的第一个语句之后再执行。但是,如果线程2一被创建就立刻运行(返回的指针还没来得及写入到mThread),那么线程2就是在尝试访问空指针或内存中的任意位置(当mThread未初始化时)。
解决方法是:引入条件变量来固定执行顺序。一种修改如下:
pthread_mutex_t mtLock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t mtCond = PTHREAD_COND_INITIALIZER;
int mtInit = 0;
//Thread 1::
void init() {

mThread = PR_CreateThread(mMain, …);
// signal that the thread has been created…
pthr

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值