自旋锁:

和信号量不同的是自旋锁可在不能休眠的代码中使用,如中断处理例程。在正确使用时,自旋锁通常比信号量具有更高的性能。

如果锁可用,则锁定位被设置,代码继续进入临界区;相反则代码进入忙循环并重复检查锁,直到该锁可用。

所有自旋锁在本质上是不可中断的,一旦调用了spin_lock,在获得锁之前一直处于自旋状态。

自旋锁的实现由于linux所支持的架构不同而不同。

自旋锁的核心规则是:任何拥有自旋锁的代码必须是原子的。自旋锁不能休眠。

自旋锁必须在可能的最短时间内拥有。

头文件:<linux/spinlock.h>

初始化:

静态:spinlock_t lock;

动态:void spin_lock_init(spinlock_t *lock);

获取锁:

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

获得自旋锁之前禁止中断,先前的中断状态保存在flags中。

void spin_lock_irq(spinlock_t *lock);

确保释放自旋锁时应该启用中断时调用。

void spin_lock_bh(spinlock_t *lock);

获得锁之前禁止软件中断。

释放锁:

void spin_unlock(spinlock_t *lock);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);

void spin_unlock_irq(spinlock_t *lock);

void spin_unlock_bh(spinlock_t *lock);

非阻塞自旋锁:

int spin_trylock(spinlock_t *lock);

int spin_trylock_bh(spinlock_t *lock);

获得自旋锁返回非零值,否则返回零。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/spinlock.h>static int major = 277;
static int minor = 0;
static dev_t helloNum;
static struct class *helloClass = NULL;
static struct device *helloDev = NULL;
static spinlock_t lock;
int busyFlag = 0;int hello_open(struct inode *pinode, struct file *pfile)
{printk("hello_open, minor:%d, major:%d\n", iminor(pinode), imajor(pinode));spin_lock(&lock);if (1 == busyFlag){spin_unlock(&lock);return -EBUSY;}busyFlag = 1;spin_unlock(&lock);return 0;
}int hello_release(struct inode *pinode, struct file *pfile)
{printk("hello_release, minor:%d, major:%d\n", iminor(pinode), imajor(pinode));busyFlag = 0;return 0;
}static struct file_operations hello_ops = {.open = hello_open,.release = hello_release,
};static int hello_init(void)
{int ret = 0;printk("hello_init\n");ret = register_chrdev( major, "hello", &hello_ops);if(ret < 0){printk("register_chrdev failed.\n");return ret;}helloClass = class_create(THIS_MODULE, "hellocls");if (IS_ERR(helloClass)) {printk("class_create failed.\n");ret = PTR_ERR(helloClass);goto error_exit1;}helloNum = MKDEV(major,minor);printk("major:%d, minor:%d\n", MAJOR(helloNum), MINOR(helloNum));helloDev = device_create(helloClass, NULL, helloNum, NULL, "hello0");if (IS_ERR(helloDev)) {printk("device_create failed.\n");ret = PTR_ERR(helloDev);goto error_exit2;}return 0;error_exit2:class_destroy(helloClass);error_exit1:unregister_chrdev(major,"hello");return ret;
}static void hello_exit(void)
{printk("hello_exit\n");device_destroy(helloClass, helloNum);class_destroy(helloClass);unregister_chrdev(major,"hello");
}MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

读取者/写入者自旋锁(了解):

运行任意数量的读取者进入临界区,但写入者必须互斥访问。

rwlock和rwsem类似。

头文件:<linux/spinlock.h>

初始化:

rwlock_init(rwlock_t *lock);

读取者:

void read_lock(rwlock_t *lock);

void read_lock_irqsave(rwlock_t *lock, unsigned long flags);

void read_lock_irq(rwlock_t *lock);

void read_lock_bh(rwlock_t *lock);

void read_unlock(rwlock_t *lock);

void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);

void read_unlock_irq(rwlock_t *lock);

void read_unlock_bh(rwlock_t *lock);

注:没有read_trylock函数。

写入者:

void write_lock(rwlock_t *lock);

void write_lock_irqsave(rwlock_t *lock, unsigned long flags);

void write_lock_irq(rwlock_t *lock);

void write_lock_bh(rwlock_t *lock);

int write_trylock(rwlock_t *lock);

void write_unlock(rwlock_t *lock);

void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);

void write_unlock_irq(rwlock_t *lock);

void write_unlock_bh(rwlock_t *lock);

linux驱动22:自旋锁spinlock相关推荐

  1. 【Linux kernel】自旋锁和互斥锁

    内核当发生访问资源冲突的时候,可以有两种锁的解决方案选择: 一个是原地等待 一个是挂起当前进程,调度其他进程执行(睡眠) Linux内核提供了自旋锁和互斥锁的机制,两者都能保证在同一时刻只有一个执行单 ...

  2. 【Linux 多线程】自旋锁与互斥锁区别

    POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套API.线程同步是并行编程中非常重要的通讯手段,其中最典型的应用就是用 Pthreads提供的锁机制(lock)来对多 ...

  3. 自旋锁SpinLock小案例

    自旋锁(spinlock) 是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU

  4. 自己动手实现自旋锁(spinlock)

    大多数的并行程序都需要在底层使用锁机制进行同步,简单来讲,锁无非是一套简单的原语,它们保证程序(或进程)对某一资源的互斥访问来维持数据的一致性,如果没有锁机制作为保证,多个线程可能同时访问某一资源,假 ...

  5. 【转】自旋锁-SpinLock(.NET 4.0+)

    短时间锁定的情况下,自旋锁(spinlock)更快.(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用.所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待.对于多核CPU而 ...

  6. linux多线程:自旋锁

    目录 1.概述 2.spin lock 锁相关的API 2.1.初始化自旋锁 2.2.获得一个自旋锁 2.3.尝试获取一个自旋锁 2.4.释放(解锁)一个自旋锁 2.5.销毁一个自旋锁 3.Mutex ...

  7. Linux内核同步方法——自旋锁(spin lock)

    自旋锁 Linux的的内核最常见的锁是自旋锁.自旋锁最多只能被一个可执行线程持有.如果一个执行线程试图获得一个被已经持有(争用)的自旋锁,那么该线程就会一直进行忙循环-旋转-等待锁重新可用要是锁未被争 ...

  8. linux内核的自旋锁

    前言 感谢宋老师. 自旋锁(Spin Lock)是一种典型的对临界资源进行互斥访问的手段,其名称来源于它的工作方式.为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置(T ...

  9. linux并发控制之自旋锁

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

最新文章

  1. 一个交换程序的通用版本
  2. 在Leaflet地图上集成Echarts
  3. winmerge 注意事项
  4. hdu 2962 最短路+二分
  5. Activiti Modeler发布以及教程
  6. vue3源码中的最长递增子序列
  7. ASP.NET Web API简单学习
  8. C语言 最大公约数和最小公倍数计算
  9. Android 系统(222)---Android 的lowmemorykiller机制
  10. 使用Dev-C++查看vector数组中的变量值
  11. 时间日期、查找、压缩类
  12. 元器件及测量基础实验
  13. 块/文件/对象三种存储的优缺点
  14. C语言 · 求arccos值
  15. java开发人员工资多少钱_全世界有多少Java开发人员?
  16. 期待重磅升级的梅李大梦想城亲子游乐园!第三代黄桥大梦想城先让你一饱眼福!
  17. 【C/C++】char * ,char ** ,char a[ ] ,char *a[]
  18. wxpython的简单使用【代码实现】
  19. [iOS]Win8下iTunes无法连接iPhone版本的解决方法
  20. 按键脚本c语言,按键精灵脚本(示例代码)

热门文章

  1. 微调背后发生了什么?
  2. java线程池面试题有哪些?java线程池常见面试题
  3. 内审员和外审员哪个含金量高一点?
  4. 八字命理应用drools规则引擎
  5. 浙江上海全国各地手机流量查询工具
  6. iptable 详解_iptable详解-阿里云开发者社区
  7. popstate_操纵浏览器历史记录--popstate() history.pushState()
  8. 不想卷了?这几家“养老型”互联网公司了解一下
  9. shopee校招笔试考什么?如何准备笔试?
  10. 程序员常用英语词汇(028)