Linux -- 互斥的底层实现
lock 和 unlock 的汇编伪代码如下:
lock:
movb $0,%al
xchgb %al,mutex
if(al 寄存器的内容>0)
return 0;
else
挂起等待;
goto lock;
unlock:
movb $1,mutex
唤醒等待 mutex 的线程;
return 0;
我们来理解以下上面的代码。
首先线程 1 申请锁,此时寄存器 %al 中的值为 0,假设内存中 mutex 的值为 1,运行到 xchgb %al,mutex 这行代码时,交换 %al 和 mutex 的值,由于在这个语句中交换的操作是原子的,所以 %al 的值变为 1,mutex 的值变为 0 的整个过程不会被打断,交换过程是安全的!此时线程 1 申请锁成功,加锁成功。
一段时间后,线程 1 被切走了。
CPU 寄存器硬件只有一套,CPU寄存器内部的数据,属于线程的硬件上下文,是线程私有的,所以寄存器 %al 的值 1 被带走了。但是存储在内存中的数据是所有线程共享的,所以 mutex 的值依旧为 0.
此时轮到线程 2 申请锁了,线程 2 也要重复上面的操作,但此时 mutex 的值已经不是 1 了,而是 0,寄存器 %al 内的值依旧为 0,交换完成后,进行 if 判断,发现寄存器 %al 内的值不是大于 0 的,说明互斥锁已经被别的线程申请走了,所以线程 2 被挂起等待,并且回到开头处,循环式的检测锁是否被释放了。
当线程 1 释放锁时,再次交换 mutex 和 寄存器 %al 的值,mutex 的值被恢复为 1,%al 中的值恢复为 0 。当线程 2 申请锁,交换 mutex 和 寄存器 %al 的值,发现寄存器 %al 中的值变为 1 了,if 语句判断结果为真,说明线程 2 申请锁成功,加锁成功!
原文地址:https://blog.csdn.net/2301_76973016/article/details/144708205
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!