操作系统概念-6.4章节-硬件同步-采用指令test_and_set()的互斥实现原理解析

操作系统概念 6.4章节 硬件同步之采用指令test_and_set()的互斥实现原理解析

1、技术背景

书中原文:
通过加锁的方式来解决临界区的问题,许多现代系统提供特殊的硬件指令,用于检测和修改字的内容,或者用于原子地交换两个字(作为不可中断地指令)。我们可以采用这些特殊的指令,相对简单地解决临界区问题,在这里通过指令test_and_set()compare_and_swap()抽象了这些指令背后地主要概念。

2、问题分析

2.1 指令test_and_set()可以按照如下代码来定义:

这一指令的重要特征是:它的执行时原子的。

bool test_and_set(bool *target) 
{
    
    
	bool rv = *target;
	// 通过地址寻址,真实地修改target的值
	*target = true;

	// 返回的是传入时target的值
	return rv;
}

代码分析:
该函数通过指针传入参数target,在函数体中创建了临时变量rv来存储target的初始值,然后真实地修改target所指向内存地址的值为true,并将临时变量rv的值返回。

场景举例:

  • case1:传入参数为false,那么该函数会返回false,但过程中会真实地修改target所指向内存地址的值为true
  • case2:传入参数为true,那么该函数会返回true,此时过程中对target所指向内存地址的修改操作将不会引起变化。

2.2 采用指令test_and_set()的互斥实现原理解析

如果一台机器支持指令test_and_set(),那么可以这样实现互斥,声明一个布尔变量lock,初始化为false。进程P的结构如下代码:


/**
 * 采用指令test_and_set()的互斥实现
*/
do {
    
    
	// 进入区代码
	while(test_and_set(&lock));  
		
	// 临界区资源操作
	criricalSectionOperation();

	// 退出区代码
	lock = false;
		
	// 剩余区
	doSomethingElse();
	
} while (true);

代码分析:

从代码中可以看到共分为四块,分别是进入区、临界区、退出区和剩余区。其中进入区的while(test_and_set(&lock));语句中的lock便是我们声明的变量,它就代表着临界区资源锁的状态

场景举例:

假设当前为false,则说明当前临界区资源没有上锁。此时某进程P1想要进入临界区,由于进入区的while循环条件test_and_set(&lock)为假,当前进程可以进入临界区执行相应的操作(注意此时lock变量的值已经被test_and_set()指令修改为true),在执行完临界区操作完毕后会执行到退出区的lock = false;语句,该语句代表着对临界区资源锁的释放。

接下来解释如何如何实现的互斥

我们假设当前状态时进程P1还在执行临界区操作,而此时有另外一个进程P2也想要进入临界区,那么它也会执行相同的代码块------执行到进入区代码while(test_and_set(&lock));。由于进程P1还没有执行完临界区操作,那么它不会对临界区资源的锁进行释放,即当前变量lock的值为true,所以P2进程会在进入区的while()循环代码无限循环,从而实现了进程P1和进程P2互斥的访问临界区资源。

3、心得

由于是菜鸡自学,所以连简单的代码都需要仔细地分析才能明白其中的原理,一开始眼高手低了,看着就这么简单的几行代码看看就会了,后来分析着就感觉没那么简单,还是要踏踏实实地去举例分析才能理解的比较透彻啊!

猜你喜欢

转载自blog.csdn.net/fan1570285527/article/details/121129848