本文由该问题引入到内核锁的讨论,归纳如下
 
为什么需要内核锁?
多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理
 
有哪些内核锁机制?
(1)原子操作
atomic_t数据类型,atomic_inc(atomic_t *v)将v加1
原子操作比普通操作效率要低,因此必要时才使用,且不能与普通操作混合使用
如果是单核处理器,则原子操作与普通操作相同
(2)自旋锁
spinlock_t数据类型,spin_lock(&lock)和spin_unlock(&lock)是加锁和解锁
等待解锁的进程将反复检查锁是否释放,而不会进入睡眠状态(忙等待),所以常用于短期保护某段代码
同时,持有自旋锁的进程也不允许睡眠,不然会造成死锁——因为睡眠可能造成持有锁的进程被重新调度,而再次申请自己已持有的锁
如果是单核处理器,则自旋锁定义为空操作,因为简单的关闭中断即可实现互斥
(3)信号量与互斥量
struct semaphore数据类型,down(struct semaphore * sem)和up(struct semaphore * sem)是占用和释放
struct mutex数据类型,mutex_lock(struct mutex *lock)和mutex_unlock(struct mutex *lock)是加锁和解锁
竞争信号量与互斥量时需要进行进程睡眠和唤醒,代价较高,所以不适于短期代码保护,适用于保护较长的临界区
 
互斥量与信号量的区别?(转载但找不到原文出处)
(1)互斥量用于线程的互斥,信号线用于线程的同步
这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
(2)互斥量值只能为0/1,信号量值可以为非负整数
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问
(3)互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到
 
 
 
 
 

[转]mutex和spin lock的区别

mutex和spin lock的区别和应用(sleep-waiting和busy-waiting的区别)2011-10-19 11:43

信号量mutex是sleep-waiting。 就是说当没有获得mutex时,会有上下文切换,将自己、加到忙等待队列中,直到另外一个线程释放mutex并唤醒它,而这时CPU是空闲的,可以调度别的任务处理。

而自旋锁spin lock是busy-waiting。就是说当没有可用的锁时,就一直忙等待并不停的进行锁请求,直到得到这个锁为止。这个过程中cpu始终处于忙状态,不能做别的任务。

例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0 和Core1上。 用spin-lock,coer0上的线程就会始终占用CPU。
另外一个值得注意的细节是spin lock耗费了更多的user time。这就是因为两个线程分别运行在两个核上,大部分时间只有一个线程能拿到锁,所以另一个线程就一直在它运行的core上进行忙等待,CPU占用率一直是100%;而mutex则不同,当对锁的请求失败后上下文切换就会发生,这样就能空出一个核来进行别的运算任务了。(其实这种上下文切换对已经拿着锁的那个线程性能也是有影响的,因为当该线程释放该锁时它需要通知操作系统去唤醒那些被阻塞的线程,这也是额外的开销)

总结
(1)Mutex适合对锁操作非常频繁的场景,并且具有更好的适应性。尽管相比spin lock它会花费更多的开销(主要是上下文切换),但是它能适合实际开发中复杂的应用场景,在保证一定性能的前提下提供更大的灵活度。

(2)spin lock的lock/unlock性能更好(花费更少的cpu指令),但是它只适应用于临界区运行时间很短的场景。而在实际软件开发中,除非程序员对自己的程序的锁操作行为非常的了解,否则使用spin lock不是一个好主意(通常一个多线程程序中对锁的操作有数以万次,如果失败的锁操作(contended lock requests)过多的话就会浪费很多的时间进行空等待)。

(3)更保险的方法或许是先(保守的)使用 Mutex,然后如果对性能还有进一步的需求,可以尝试使用spin lock进行调优。毕竟我们的程序不像Linux kernel那样对性能需求那么高(Linux Kernel最常用的锁操作是spin lock和rw lock)。

spin_lock & mutex_lock的区别? 【转】的更多相关文章

  1. spin_lock & mutex_lock的区别?

    http://blog.csdn.net/sunnytina/article/details/7615520   为什么需要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是 ...

  2. 【转】spin_lock & mutex_lock的区别? .

    原文网址:http://blog.csdn.net/wilsonboliu/article/details/19190861 本文由该问题引入到内核锁的讨论,归纳如下   为什么需要内核锁? 多核处理 ...

  3. 锁(1):spin_lock & mutex_lock的区别? .

    为什么需要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理   有哪些内核锁机制? (1)原子操作 atomic ...

  4. spin_lock、spin_lock_irq、spin_lock_irqsave区别【转】

    转自:http://blog.csdn.net/luckywang1103/article/details/42083613 void spin_lock(spinlock_t *lock); voi ...

  5. spin_lock、spin_lock_irq、spin_lock_irqsave区别

    void spin_lock(spinlock_t *lock); void spin_lock_irq(spinlock_t *lock); void spin_lock_irqsave(spinl ...

  6. spin_lock & mutex_lock的差别?

    本文由该问题引入到内核锁的讨论,归纳例如以下 为什么须要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是能够訪问全部内核数据的,因此要对共享数据进行保护,即相互排斥处理 有 ...

  7. kernel_thread()和kthread_run()/kthread_create()的根本区别

    0 本质区别 kthread_run()调用kthread_create(), kthread_create()加入链表后,有kthreadd()线程读取链表然后再调用kernel_thread()创 ...

  8. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析

    转自:http://blog.csdn.net/wh_19910525/article/details/11536279 自旋锁的初衷:在短期间内进行轻量级的锁定.一个被争用的自旋锁使得请求它的线程在 ...

  9. mutex_lock

    多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理. mutex_lock(struct mutex *lock)和mute ...

随机推荐

  1. 【HDU5469】Antonidas(点分治,字符串哈希)

    [HDU5469]Antonidas(点分治,字符串哈希) 题面 HDU Vjudge 题解 啊哈?什么垃圾一眼点分治+Hash判断,哈哈哈哈哈,让我来码码码. 诶,怎么WA了.改改改改改. 诶,怎么 ...

  2. Missing $ inserted解决方法

    目录 问题描述 解决 参考 问题描述 在学习LaTex Tutorial的时候,按照教程输入矩阵的时候发现出现了 ! Missing $ inserted的错误. 解决 在矩阵前后要加上$,如图所示 ...

  3. 解题:USACO15JAN Grass Cownoisseur

    解题 首先缩点没啥可说的,然后考虑枚举这次逆行的边.具体来说在正常的图和反图上各跑一次最长路,然后注意减掉起点的贡献,用拓扑排序实现(我这里瞎写了个Bellman_Ford,其实在DAG上这好像和拓扑 ...

  4. Facenet Triplet Loss

    Triplet Loss 在人脸识别中,Triplet loss被用来进行人脸嵌入的训练.如果你对triplet loss很陌生,可以看一下吴恩达关于这一块的课程.Triplet loss实现起来并不 ...

  5. shell 变量定义使用

    shell 中变量的几种类型: 1.局部变量:只在当前 shell 可用的变量, 2.环境变量:当前 shell 的子进程也可用的变量 3.shell 变量:一些由 shell 设置的特殊变量,如:$ ...

  6. Java入门:绘制简单图形

    在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...

  7. 利用ansible来做kubernetes 1.10.3集群高可用的一键部署

    请读者务必保持环境一致 安装过程中需要下载所需系统包,请务必使所有节点连上互联网. 本次安装的集群节点信息 实验环境:VMware的虚拟机 IP地址 主机名 CPU 内存 192.168.77.133 ...

  8. Unmanaged Exports生成Dll时的一些疑难杂症疗法

    Unmanaged Exports是一个将.NET编写的静态托管函数导出成可供C/C++等直接调用的非托管函数的工具. 已经在上篇文章介绍过了,这里不再复述. 限制 你不能导出在同一个class中的重 ...

  9. codevs 1070 普通递归关系

    1070 普通递归关系  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 考虑以下定义在非负整数n上的递归关系 f( ...

  10. SQL语句(十五)视图

    视图 实际上是一个查询语句, 如果将子查询保存为视图, 就可以将子查询的结果当作数据表使用 从而来简化查询语句 引言 例1 查询参加"数据库技术"课程的考试的学生学号.姓名.班级. ...