概述
内核当发生访问资源冲突的时候,可以有两种锁的解决方案选择:
• 一个是原地等待
(
自旋锁方式
)
• 一个是挂起当前进程,调度其他进程执行(睡眠)
(
互斥锁方式
)
Spinlock 是内核中提供的一种比较常见的
锁机制
,
自旋锁是
“
原地等待
”
的方式
解决资源冲突的,即,一个线程获取了一个自旋锁后,另外一个线程期望获取该自旋锁,获取不到,只能够原地“
打转
”
(忙等待)。由于自旋锁的这个忙等待的特性,注定了它使用场景上的限制 ——
自旋锁不应该被长时间的持有
(消耗
CPU
资源)。
在 linux kernel 的实现中,经常会遇到这样的场景:共享数据被中断上下文和进程上下文访问,该如何保护呢?如果只有进程上下文的访问,那么可以考虑使用 semaphore 或者
mutex
的锁机制,但是现在
中断上下文
也参和进来,那些可以导致睡眠的 lock
就不能使用了,这时候,可以考虑使用
spin lock
。换言之,
中断上下文要用
锁,首选
spinlock
。自旋锁尽可能的减少线程的阻塞,这对于锁的竞争不激烈,且占用锁时间非常短的代码块来说性能能大幅度的提升,因为自旋的消耗会小于线程阻塞挂起再唤醒的操作的消耗,这些操作会导致线程发生两次上下文切换!
初始化自旋锁(pthread_spin_init)
头文件:
#include <pthread.h>
函数原型:
int pthread_spin_init(pthread_spinlock_t *lock int pshared);
作用:
初始化自旋锁 lock
参数含义:
lock:自旋锁
pshared:要设置的自旋锁属性,为 PTHREAD_PROCESS_PRIVATE 表示互斥锁只能在本进程中使用,为 PTHREAD_PROCESS_SHARED 表示互斥锁可以在不同进程间使用
返回值:
成功返回 0,
失败返回错误码
销毁自旋锁(pthread_spin_destory)
头文件:
#include <pthread.h>
函数原型:
int pthread_spin_destory(pthread_spinlock_t *lock);
作用:
销毁自旋锁 lock
参数含义:
lock:自旋锁
返回值:
成功返回 0,
失败返回错误码
获取自旋锁
一直获取(pthread_spin_lock)
头文件:
#include <pthread.h>
函数原型:
int pthread_spin_lock(pthread_spinlock_t *lock);
作用:
获取自旋锁 lock
并上锁,没获取到则一直循环获取
参数含义:
lock:要获取的自旋锁
返回值:
成功返回 0
失败返回错误码
直接返回的获取(pthread_spin_trylock)
头文件:
#include <pthread.h>
函数原型:
int pthread_spin_trylock(pthread_spinlock_t *lock);
作用:
获取自旋锁 lock
并上锁
,
没获取到则立即返回
参数含义:
lock:要获取的自旋锁
返回值:
成功返回 0
失败返回其他值
解锁操作(pthread_spin_unlock)
头文件:
#include <pthread.h>
函数原型:
int pthread_spin_unlock(pthread_spinlock_t *lock);
作用:
释放自旋锁 lock(
解锁
)
参数含义:
lock:要释放的自旋锁
返回值:
成功返回 0
失败返回其他值