信号量与自旋锁的简单介绍

semaphore:

信号量的特点:
1、用于进程与进程之间的同步
2、允许有多个进程进入临界区代码执行
3、进程获取不到信号量锁会陷入休眠,并让出cpu
4、被信号量锁保护的临界区代码允许休眠
5、本质是基于进程调度器,UP和SMP下的实现无差异
6、不支持进程和中断之间的同步

实际操作:

struct semaphore sema;//定义信号量变量
在驱动初始化代码中:
eg: 
int hello_int(void)
{
	.......
	sema_init(&seme, 1);//只允许一个进程运行
	.......
}	

int hello_open(struct inode *p, struct *f)
{
	down(&sema);//加锁
	if(open_count >= 1)
	{
		up(&sema);
		prink(KERN_INFO "device is busy, hello_open fail);
		return -EBUSY;
	}
	open_count++;
	up(&sema);
	prink(KERN_INFO "device is busy, hello_open ok");
	return 0;
}
int hello_close(struct inode *p, struct *f)
{
	if(open_count != 1)
	{
		up(&sema);
		prink(KERN_INFO "device is busy, hello_open fail);
		return -EBUSY;
	}
	open_count--;
	up(&sema);
	prink(KERN_INFO "device is busy, hello_open ok");
	return 0;
}

spinlock

自旋锁的特点:
1、spinlock是一个死等的锁机制
2、semaphore可以允许多个执行单元进入,spinlock不行,一次只能有一个执行单元获取锁并进入临界区,
其他的执行单元都是在门口不断的死等
3、spinlock的执行时间短,由于spinlock死等这种特性,如果临界区执行时间太长,
那么不断在临界区门口"死等"的那些执行单元就很浪费CPU资源
4、spinlock可以在终端上下文执行,由于不睡眠,因此spinlock可以在中断上下文使用

实际操作:

spinlock count_lock;//定义锁
在驱动初始化代码中:
eg: 
int hello_int(void)
{
	.......
	spin_lock_init(&count_lock);//初始化
	.......
}	

int hello_open(struct inode *p, struct *f)
{
	spin_lock(&count_lock);//加锁
	//临界区代码
	if(open_count >= 1)
	{
		spin_unlock(&count_lock);
		prink(KERN_INFO "device is busy, hello_open fail);
		return -EBUSY;
	}
	open_count++;
	spin_unlock(&count_lock);
	prink(KERN_INFO "device is busy, hello_open ok");
	return 0;
}
int hello_close(struct inode *p, struct *f)
{
	if(open_count != 1)
	{
		spin_lock(&count_lock);
		prink(KERN_INFO "device is busy, hello_open fail);
		return -EBUSY;
	}
	open_count--;
	spin_unlock(&count_lock);
	prink(KERN_INFO "device is busy, hello_open ok");
	return 0;
}

spinlock的系列函数:

//进程与进程之间的同步
void spin_lock(spinlock_t *lock)
//涉及到和本地软中断之间的同步
void spin_lock_bh(spinlock_t *lock)
//涉及到和本地硬件中断之间的同步
void spin_lock_irq(spinlock_t *lock)
//涉及到和本地硬件中断之间的同步并保存本地中断状态
void spin_lock_irqsave(lock, flags)
//尝试获取锁,如果成功返回非零值,否则返回零值
int spin_trylock(spinlock_t *lock)

spinlock、rw spinlock、seqlock、rcu机制比较:

1、rw(read/write)spinlock
1.1、加锁的逻辑
(1)假设临界区没有任何的thread,这时候任何read thread或者write thread可以进入;
(2)假设临界区内有一个read thread,这时候新来的read thread可以任意进入,但是write thread不可以进入;
(3)假设临界区内有一个write thread,这时候任何的read thread或者write thread都不可以进入;
(4)假设临界区内有一个或者多个read thread,write thread当然不可以进入临界区,但是该write thread也无法阻止后续read thread的进入
他要一直等到临界区一个read thread也没有的时候,才能进入。
由此可见,rw spinlock给reader赋予了更高的优先级。

2、seqlock(顺序锁)
2.1、加锁的逻辑
(1)假设临界区没有任何的thread,这时候任何read thread或者write thread可以进入;
(2)假设临界区没有一个write thread,read thread可以随意进入,也就是说reader不会阻挡reader;
(3)假设临界区有一个write thread,这时候任何的read thread或者write thread都不可以进入;
(4)假设临界区只有read thread时,write thread可以立刻执行,不会等待
由此可见,seqlock给writer赋予了更高的优先级。

3、spinlock的不足
3.1、性能问题:
RW spin lock、spin lock和seqlock,它们都是基于一个memory中的共享变量(对该变量的访问是原子的)

4、各个锁机制比较
(1)spin lock不区分reader和writer,对于那些读写强度不对称的是不合适的;
(2)RW spin lock和seq lock解决了这个问题,不过seq lock倾向于writer,而RW spin lock更照顾reader;
(3)为什么还有RCU?
随着计算机硬件技术的发展,CPU相对于存储器件的运算速度优势越来越大,在这种背景下,
获取基于counter(需要访问存储期间)的锁(例如spin lock、rw lock)的机制开销越来越明显。
因此,那些基于一个multi-processor之间的共享的counter的锁机制已经不能满足性能的需求,
这也就有了RCU机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值