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


    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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机制

  • 相关阅读:
    通信原理学习笔记6-4:数字解调——抽样判决的译码准则(最大后验概率准则MAP、最大似然准则ML、最小二乘/最小平方准则LS、最小距离准则)
    如何在微信公众号正文中添加附件?
    接雨水问题
    软件License授权原理
    智能升降桌控制主板开发,解锁办公家居新场景
    利用霍夫变换进行车道线检测
    明道云在艾默生数字化实践的新进展
    【Android知识笔记】UI体系(五)
    [NOIP2013 普及组] 计数问题
    java基于springcloud+vue+elementui的养老院管理系统 前后端分离
  • 原文地址:https://blog.csdn.net/shark_93/article/details/127629663