Linux 设备驱动 ====> 并发控制 --- 自旋锁

原创 2012年03月28日 09:09:35

自旋锁的使用

自旋锁(spin_lock)是一种典型的对临界资源进行互斥访问的手段,顾名思义,为了获得一个自旋锁,在某CPU上运行的代码需要先执行一个原子操作,该操作测试并设置某个内存变量,在该操作完成之前其他执行单元不可能访问到这个内存变量。

如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行;如果测试表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置”操作,就是“自旋”的动作,就是原地打转。当自旋锁的持有者通过重置该变量释放这个自旋锁后,某个等待的“测试并设置”操作向其调用者报告锁已经释放。

Linux中自旋锁的操作

1. 定义自旋锁

spinlock_t lock;

2 初始化自旋锁

spin_lock_init(lock);

用于动态初始化自旋锁。

3. 获得自旋锁

spin_lock(lock);

该宏用于获得自旋锁lock,如果能够立即获得锁,马上返回,否则,它将自旋在那里直到锁被释放。

spin_trylock(lock);

尝试获得自旋锁lock,如果能后立即获得锁,返回真,否则立即返回假,也就是说不会再“原地打转”。

4. 释放自旋锁

spin_unlock(lock);

释放自旋锁lock,与lock和trylock配套使用。

5. 用法

//declear a spin lock
spinlock_t lock;
spin_lock_init(&lock);

spin_lock(&lock);        //获得自旋锁
...                      //临界区
spin_unlock(&lock);      //解锁

自旋锁主要用于SMP或者单CPU内核抢占的情况下使用。

驱动工程师应谨慎使用,下面是需要注意的地方:

1. 自旋锁是忙等待,在得不到锁的时候会一直“测试并设置”,这样的话如果长时间得不到锁会浪费系统资源,所以适合用在等待时间比较短的情况下,不然会降低系统的性能。

2. 自旋锁可能会导致系统死锁。当2次试图获得这个自旋锁的时候,CPU会死锁。

3. 自旋锁锁定期间不能调用可能引起进程调度的函数,如果进程获得自旋锁之后再阻塞,如调用copy_from_user()、copy_to_user、kmalloc、msleep等函数,可能会导致内核崩溃。


下面举例说明使用自旋锁实现设备只能被一个进程打开。

我们还是沿用之前的globalmem的例子加以修改

int open_count = 0;	//declear open times
spinlock_t lock;

int globalmem_open(struct inode *inode, struct file *filp)
{
	spin_lock(&lock);
	if(open_count) {	// already open
		printk(KERN_ERR "already open!\n");
		spin_unlock(&lock);
		return -EBUSY;
	}
	open_count++;
	spin_unlock(&lock);
	printk(KERN_INFO "globalmem open!\n");
	filp->private_data = globalmem_devp;	
	return 0;
}

int globalmem_release(struct inode *inode ,struct file *filp)
{
	spin_lock(&lock);
	open_count--;
	spin_unlock(&lock);
	printk(KERN_INFO "globalmem release!\n");
	return 0;
}

在init函数中初始化

int globalmem_init(void)
{
	int result;
	spin_lock_init(&lock);

然后我们重新编译并添加模块,然后使用上篇中的测试app来测试,当我们运行测试程序的时候,马上再去打开globalmem的时候会提示设备忙。

jay@jay:/dev$ cat globalmem 
jay@jay:/dev$ echo "123" > globalmem 
jay@jay:/dev$ cat globalmem 
cat: globalmem: Device or resource busy
jay@jay:/dev$ echo "123" > globalmem 
bash: globalmem: Device or resource busy
jay@jay:/dev$ 

自旋锁就简单的介绍到这,结束。

=========================================================

mail & MSN :zhangjie201412@live.com

=========================================================


相关文章推荐

linux设备驱动--并发与竞态之自旋锁

自旋锁(spin lock)是一种典型的对临界资源进行互斥访问的手段。与信号量不同,自旋锁可在不能休眠的代码中使用,比如中断处理例程。(自旋锁api的一些衍生都是与中断相关的)在正确使用的情况下,自旋...
  • dndxhej
  • dndxhej
  • 2012年03月10日 20:04
  • 1223

Linux 驱动之并发控制 (信号量、原子锁和自旋锁)

摘要:并发控制,是多任务操作系统必须面临和解决的一个问题。并发与互斥,主要是用于保护临界资源,如果不站在操作系统进程调度的角度,就很难理解并发与互斥的概念和应用。无论是抢占式操作系统,还是分时操作系统...

Linux驱动编程 step-by-step (七) 并发 竞态 (信号量与自旋锁)

并发 竞态 (信号量与自旋锁) 代码传至并发竞态控制 并发进程 导致竞态的一个例子 前面所述的字符驱动都是没有考虑并发竟态的情况,想象一下 一个进程去读一个字符设备,另一个进程在同...

linux 驱动编程___竞态/并发问题___自旋锁

~  自旋锁自旋锁的几点说明 与信号量不同, 自旋锁可在不能休眠的代阿中使用, 比如中断处理例程 一个自旋锁就是一个互斥设备, 只有两个状态: 锁定 和 解锁 自旋锁是某个整数值的单个位, 希...

驱动程序学习(四)并发控制(2)自旋锁控制

在概念上,自旋锁非常简单。一个自旋锁就是一个互斥设备,它只有两个值:“锁定” 和“解锁”。它通常实现为某个整数值中的单个位。希望获得某特定锁的代码测试的相关 的位。如果锁可用,则“锁定”位被设置,...

linux并发控制之自旋锁

自旋锁是一种对临界资源进行互斥访问的典型手段,其名来源于它的工作方式。 通俗的讲,自旋锁就是一个变量,该变量把一个临界区标记为“我当前在运行,请等待”或者标记为“我当前不在运行,可以被使用”, 如果...

linux并发控制之读写自旋锁

读写自旋锁(rwlock)是一种比自旋锁粒度更小的自旋锁机制,它保留了“自旋”的概念。 但是在写操作方面,只能最多有一个写进程,在读方面,同时可拥有多个执行单元,当然读和写也不能同时进行。 一句话...

linux驱动 自旋锁

最近在内核频繁使用了自旋锁,自旋锁如果使用不当,极易引起死锁,在此总结一下。 自旋锁是一个互斥设备,它只有两个值:“锁定”和“解锁”。它通常实现为某个整数值中的某个位。希望获得某个特定锁得代码测试相...
  • o0o0o0D
  • o0o0o0D
  • 2016年11月01日 19:42
  • 141

linux 自旋锁讨论记录

  • 2010年08月06日 21:40
  • 449KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 设备驱动 ====> 并发控制 --- 自旋锁
举报原因:
原因补充:

(最多只允许输入30个字)