进程/线程互斥的实现方式

首先介绍几个相关概念。

临界资源:在同一时刻,只能被一个进程/线程所使用的资源。
临界区:访问临界资源的代码段。因此同一时刻只能有一个进程/线程进入临 界区。
进入区:进入临界区之前的代码段,一般用来做加锁操作。
退出区:临界区执行之后的代码段,一般用来释放锁。

下面介绍几种进程/线程同步的实现方式

1.硬件方式-关中断。在代码执行处于进入区时,执行关中断指令,在退出区时执行开中断指令。CPU忽略中断信号,自然就不会发生进程/线程调度,保证了单核情况下只有一个进程/线程访问临界资源。然而只有执行了关中断指令的CPU会忽略中断信号,其他CPU核心仍然会不断发生进程/线程调度,因此关中断无法在多核情况下保证对于临界资源的互斥访问。

2.软件方式-皮特森算法。
在这里插入图片描述皮特森算法是一种纯软件实现方法,并且能够保证在多核情况下对于临界资源的互斥访问。但是皮特森算法要求访存操作严格按照顺序执行,然而现代CPU为了更好的性能往往允许访存操作乱序执行,皮特森算法在这类CPU上无法正确执行。(具体过程不做赘述,感兴趣可以自行搜索了解)

3.软硬件结合-使用硬件提供的原子操作(CAS等)编写代码完成线程互斥。硬件为我们提供了一些原子操作,例如CAS、FAA,使用这些原子操作,我们能设计新的算法解决临界区问题。
CAS,即Compare And Swap,比较并交换,一般需要三个操作数,一个地址值addr,一个所期望的旧值expected,一个新值newValue。只有当addr所存的数与expected相等时,才将newValue存入addr处。抽象成C语言代码如下所示(代码仅仅只是描述其含义,并非真正的实现)

int CAS(int *addr, int expected, int newValue){
	int oldValue = *addr;
	if (*addr == expected) {
		*addr = newValue;
	} 
	return oldValue;
}

对于CAS原子操作,不同的硬件平台提供有不同的实现。比如Intel平台提供的带lock前缀的cmpxchg指令,lock前缀保证了多核情况下的原子性,因为单核情况下,一条指令(完成CAS操作)本身就是原子的,但是其他核心仍然是可以访问并修改该addr地址的,这就有可能导致出现错误,因此在多核情况下需要做额外操作,早期的处理是锁总线,现代硬件采用了锁缓存等操作(感兴趣可以自行搜索了解),来保证多核情况下,CAS操作的原子性。

通过CAS操作,我们可以实现互斥锁,用一个变量来表示锁状态,在进入临界区之前,通过CAS来将锁置为上锁状态,在退出临界区时将锁释放,代码抽象如下所示

int lock = 0; //锁变量,0为未上锁,1为加锁状态,初始时为0

//加锁
void lock(){
	while (CAS(&lock,0,1) != 0) {
		;
	}
}

//释放锁
void unLock(){
	lock = 0; //这里不需要使用CAS,可以想想为什么
}

通过上述lock,unLock方法,可以实现线程的互斥。在执行lock()方法时,如果lock原本的值不为0,那么将一直执行while循环,直到lock为0。因此该锁也称为自旋锁。
自旋锁的实现简单易懂,但有一个很明显的缺点就是它不能保证有限等待,也就是说,很多个线程执行lock()方法时,竞争十分激烈,有可能其中一个线程永远也无法跳出CAS循环。即使如此,自旋锁仍然应用十分广泛,原因就是它在线程竞争程度不高时效率突出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
进程线程)同步互斥是指当多个进程线程)同时运行时,它们之间可能会存在共享资源的竞争问题,而同步互斥的目的就是为了解决这些竞争问题。同步是指多个进程线程)在执行过程中需要相互配合,才能保证程序的正确性和可靠性。互斥是指多个进程线程)之间相互排斥,同一时刻只允许一个进程线程)访问共享资源,其他进程线程)必须等待,直到该进程线程)访问结束。 常见的进程线程)同步互斥方式有: 1. 信号量:信号量是一种计数器,用于保护多个进程线程)对共享资源的访问。当进程线程)想要访问共享资源时,会尝试获取信号量,如果当前信号量的值大于0,则允许访问;否则需要等待,直到有一个进程线程)释放了信号量。 2. 互斥量:互斥量是一种特殊的信号量,它只有两个取值:0和1。当进程线程)想要访问共享资源时,需要先尝试获取互斥量,如果当前互斥量的值为0,则表示该共享资源被占用,需要等待;如果当前互斥量的值为1,则表示该共享资源未被占用,可以访问,并将互斥量的值设置为0,防止其他进程线程)同时访问。 3. 条件变量:条件变量是一种用于在多个进程线程)之间传递消息的机制。当某个条件满足时,一个进程线程)会通知其他等待该条件的进程线程),使它们可以继续执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值