Linux设备驱动程序第三版学习(4)- 并发和竟态 .

时间:2022-06-25 23:36:23

第五章学习:并发和竟态
其实可以拿上“公共厕所”来做一个比喻,就是那种在大街上只有一个隔间的小型公厕。更容易理解并发、竟态和信号量。
把“临界区”理解为“公共厕所”(临界区:在任意给定的时刻,代码只能被一个线程执行。/ 公共厕所:在任意给定的时刻,厕所只能被一个人使用。),“公共厕所”的来源是“并发”的(很多人可以一起去上厕所),假设A同学已经进去了,如果厕所什么标记都没有(没有信号量),那么B同学来的时候不知道里面有人就推门而入,这时候就尴尬了(错误发生了)。这个过程就是竟态(race condition)。为了避免这种尴尬,人们想出了一个办法,于是我们在门上挂了个牌子(信号量),牌子的一面用红色字写着“使用中”(也就是‘0’),另一面用绿色字写着“空闲”(也就是‘1’), 初始状态是“空闲”(调用init_MUTEX,这实际上是调用了sema_init(sem, 1),可以查看semaphore.h)。这样,当A同学进去时,先把红色字翻过来(调用down_interruptible成功,获得信号量),好了,当B同学急匆匆赶来时,发现厕所是“使用中”的状态(也是调用down_interruptible,结果得到了一个非零值),很郁闷(没能获得信号量),于是B同学只好先干点别的事,打个酱油什么的。当A同学出来时,必须把“空闲”翻出来(调用up将信号量+1),否则就是占着茅坑不拉屎了,会被鄙视的。
另外linux的P有三个版本,最为常用的就是down_interruotible,这个版本是可中断的。如果操作被中断,该函数会返回非零值,而调用者不会拥有该信号量。还拿上个例子打比方吧,A同学在翻牌子的时候突然接到mm的电话,要求给她买冰淇淋,这个中断不可忽视阿,上厕所?先忍着吧!于是牌子还是“空闲”(没有获得信号量)。
理解读取者/写入者信号量(rwsem)。该信号量是为了提高性能而设计的。该信号量可允许一个写入者或无限多个读取者拥有该信号量。因为允许多个并发的读取者是可能的,只要它们之中没有哪个要做修改。还是拿上面的例子做个比喻,把来厕所的分为两种人:一种是要方便的,另一种是要参观的(it is ridiculous, but it works. haha)。好吧,要方便的人必须一个一个进(互斥),参观的可以一起进,但是参观的和方便的不能一起进。这时候就要多出个牌子来,这个牌子写“参观中”(这就是rwsem),所有参观者看到这个牌子都可以进去。而当最后一个参观者出来时,需要把“空闲”的牌子翻出来(调用up_read)。