自旋锁与互斥锁的区别

编程世界中,锁用来保护一个资源不会因为并发操作而引起冲突,导致数据不准确。

常见的锁有互斥锁、读写锁、自旋锁、信号量、分布式锁等等。

这里仅仅讨论互斥锁和自旋锁的区别。

自旋锁是当资源被占用时,锁逻辑循环判断资源是否可用,而不是把进程挂起,直到资源可用。
自旋锁采用的是,循环等待资源可用,而不是挂起当前线程或者进程,因为在某些场景中,CPU挂起线程或者进程的开销更大。
因此,自旋锁适用于对共享资源占用时间比较小的场景中。

与自旋锁不同的互斥锁,在加锁失败后,如果资源不可用,当前锁所在线程会阻塞释放CPU ,给其他线程使用。

自旋锁和互斥锁均属于悲观锁.

附Golang中 自旋锁的实现:

//SpinLock.go

package main

import (
	"fmt"
	"sync/atomic"
	"time"
)

type Locker interface {
	Lock()
	Unlock()
}

type SpinLock int32

func (sl *SpinLock) Lock() {
	for !atomic.CompareAndSwapInt32((*int32)(sl), 0, 1) {
		// fmt.Printf("locked")
	}
}

func (sl *SpinLock) Unlock() {
	atomic.StoreInt32((*int32)(sl), 0)
}

func main() {
	l := new(SpinLock)

	v := 0
	for i := 0; i < 2; i++ {
		go func(t int) {
			for v < 1000 {
				l.Lock()
				v++
				l.Unlock()
				fmt.Printf("t%d: %d\n", t, v)
				time.Sleep(1 * time.Millisecond)
			}
		}(i)
	}

	for v < 1000 {
		<-time.After(100 * time.Millisecond)
	}
}
posted @ 2024-05-29 09:06  zongzw  阅读(81)  评论(0)    收藏  举报