zoukankan      html  css  js  c++  java
  • linux 自旋锁的使用

    今天和两位群友讨论了很长一段自旋锁的使用方法,记录下来,以后参考:

    北京-司令(117838621)  19:50:25
    大家好,有谁理解自旋锁。。。?
    北京-司令(117838621) 19:51:02
    我是否可以再open里面加锁,release里面解锁呀..?

    键指江山(1791120766) 19:51:17
    不行!
    北京-司令(117838621) 19:51:21
    ?
    键指江山(1791120766) 19:51:40
    自旋锁只允许短时间锁定
    北京-司令(117838621) 19:51:46
    为什么,这样不就是只允许app一个进程可以打开这个设备
    键指江山(1791120766) 19:51:49
    这样的话你应该用信号量
    北京-司令(117838621) 19:52:14
    楼上说的很好。。。不过为什么这个不行呢。。。
    北京-司令(117838621) 19:52:35
    我试了一下,竟然系统死机了。。(我app调用了2次)
    键指江山(1791120766) 19:52:37
    或者用complete
    键指江山(1791120766) 19:52:41
    肯定死机
    城关少主(1007936447) 19:52:45
    要不然待锁的进程会移植占有CPU
    北京-司令(117838621) 19:52:48

    键指江山(1791120766) 19:52:51
    导致死锁
    键指江山(1791120766) 19:53:14
    什么叫自旋?
    键指江山(1791120766) 19:53:25
    类似于while(1)
    北京-司令(117838621) 19:53:27
    我是否可以再open里面加锁,release里面解锁呀..?
    ,我的意思是,我一个app打开,处理完后close后不久解锁了。。。?
    北京-司令(117838621) 19:53:36
    何来自锁。。。?
    阿九(617330220) 19:53:40
    死锁了当然死机
    键指江山(1791120766) 19:53:47
    自旋锁不是这么用的
    阿九(617330220) 19:53:40
    死锁了当然死机
    键指江山(1791120766) 19:54:04
    complete
    键指江山(1791120766) 19:54:18
    加锁的目的?
    北京-司令(117838621) 19:54:28
    而另一个app在得到锁这个地方就忙等了。。一直等到第一个app close不就行了。。。
    键指江山(1791120766) 19:54:34
    锁保护的只是数据,不是代码
    键指江山(1791120766) 19:54:51
    那你就不能用自旋锁啊。
    北京-司令(117838621) 19:55:06
    我知道,这个用信号量道理我明白。。
    键指江山(1791120766) 19:55:05
    你就用信号量
    键指江山(1791120766) 19:55:28
    自旋锁一般是锁很短的时间内
    键指江山(1791120766) 19:55:41
    因为自旋锁锁定过程中不允许睡眠
    键指江山(1791120766) 19:55:49
    会关掉内核的抢占
    北京-司令(117838621) 19:55:59
    结果呢
    键指江山(1791120766) 19:56:13
    结果就出现那种现象了
    北京-司令(117838621) 19:56:15
    也就是说当前进程一直占用cpu
    键指江山(1791120766) 19:56:21

    键指江山(1791120766) 19:56:33
    然后你那个close怎么去执行?
    键指江山(1791120766) 19:56:50
    内核对内核代码是没有安全检查的
    键指江山(1791120766) 19:56:55
    很信任的
    北京-司令(117838621) 19:57:08
    那不更好么?它一直占用cpu,岂不很快就把app执行完了,然后close,然后就释放锁呀。。。
    键指江山(1791120766) 19:57:15

    北京-司令(117838621) 19:57:22

    键指江山(1791120766) 19:57:29
    你的是多核还是单核额
    北京-司令(117838621) 19:57:31
    怎么了。。我说的不对么?
    键指江山(1791120766) 19:57:31
    大哥
    北京-司令(117838621) 19:57:37
    单核呀
    键指江山(1791120766) 19:57:54
    是等待锁的那个进程在占用CPU。。。。。
    北京-司令(117838621) 19:57:56
    驱动中占用cpu,那么是app调用drv的。。。
    键指江山(1791120766) 19:57:59
    你说呢
    键指江山(1791120766) 19:58:18
    你的close怎么执行?
    北京-司令(117838621) 19:58:29
    你的意思是第二个app占用么?
    键指江山(1791120766) 19:58:33
    你可以做做实验用printk什么的输出看看
    键指江山(1791120766) 19:58:40
    应该是

    北京-司令(117838621) 19:58:45
    我什么也输出不来。。。
    键指江山(1791120766) 19:59:06
    那不就是没跑到哪里去嘛
    北京-司令(117838621) 19:59:13
    不过按你说的,那么短时间的锁,岂不也执行不了了。。。
    键指江山(1791120766) 19:59:35
    此话怎讲?
    北京-司令(117838621) 20:00:29
    比如说:
    spin_lock(&spin);
    //临界资源访问
    globalvar_count++;
    spin_unlock(&spin);
    键指江山(1791120766) 20:00:47

    键指江山(1791120766) 20:01:00
    中间好像一睡眠就肯定出问题
    键指江山(1791120766) 20:01:26
    好像scheduler就有问题

    键指江山(1791120766) 20:01:30
    做做实验看
    北京-司令(117838621) 20:01:35
    当我第一个app得到锁了,执行globalvar_count++; 谁知还没执行,第二个app又开始获锁,那么第二个app就死了,在占用cpu,那么globalvar_count++; 还怎么执行。。。
    键指江山(1791120766) 20:02:18
    等等
    键指江山(1791120766) 20:02:21
    我想想
    键指江山(1791120766) 20:02:31
    我觉得应该是scheduler就会出问题
    北京-司令(117838621) 20:02:38

    键指江山(1791120766) 20:02:46
    有任务调度
    键指江山(1791120766) 20:02:49
    就会出问题
    北京-司令(117838621) 20:02:58
    怎么个说法
    键指江山(1791120766) 20:03:08
    因为spin_lock(&spin);会禁止抢占和SMP
    键指江山(1791120766) 20:03:24
    我等会做下实验看
    北京-司令(117838621) 20:03:29
    好的。。。
    键指江山(1791120766) 20:03:33
    兄弟,建议你也做做实验
    键指江山(1791120766) 20:03:48
    这玩意就是多看多试
    北京-司令(117838621) 20:03:50
    嘻嘻。。
    北京-司令(117838621) 20:03:56
    我就是一直死。。。
    键指江山(1791120766) 20:04:05
    看下LDD3
    键指江山(1791120766) 20:04:10
    强烈推荐
    键指江山(1791120766) 20:04:12
    呵呵
    北京-司令(117838621) 20:04:12
    不过我试过了后面的那个做法。。是可以执行的。。。
    北京-司令(117838621) 20:04:28
    我看了一半,有点看不下去了。呵呵
    键指江山(1791120766) 20:05:09
    是比较枯燥
    无锡-萝卜(136904743) 20:05:20
    cramfs 挂载 yaffs2 怎么样才算陈公告挂载yaffs2
    键指江山(1791120766) 20:05:21
    我的眼都看大了
    键指江山(1791120766) 20:05:25
    看了好几本
    北京-司令(117838621) 20:05:34
    呵呵。。。
    键指江山(1791120766) 20:05:53
    UNIX高级编程3本+LDD3+深入理解Linux内核
    键指江山(1791120766) 20:06:05
    还得多实践
    阿九(617330220) 20:06:22
    LDD3是讲什么的??
    北京-司令(117838621) 20:06:39
    我一般使用信号量。。。不用自旋锁,不过近来找到本《linux设备驱动开发入门》照着上面在试验着。。。
    键指江山(1791120766) 20:06:38
    yaffs2是做root文件系统吗?
    键指江山(1791120766) 20:06:53
    这玩意还是要系统的看看
    键指江山(1791120766) 20:07:04
    对应用编程最好也多了解下
    北京-司令(117838621) 20:07:07
    对,是的。。
    键指江山(1791120766) 20:07:24
    很多问题就明白了
    键指江山(1791120766) 20:07:31
    要不总是云里雾里
    键指江山(1791120766) 20:09:20
    阿九兄弟 LDD3就是Linux Device Driver
    键指江山(1791120766) 20:09:40
    Edition3



    郑州-司令(117838621)  20:16:00
    大家好,有谁理解自旋锁。。。?

    我是否可以再open里面加锁,release里面解锁呀..?
    雄哥(309683352) 20:25:25
    你自旋锁是锁什么数据的啊
    雄哥(309683352) 20:27:29
    自旋锁一般是多cpu或是可抢占内核中断上下文中使用
    郑州-司令(117838621) 20:27:51
    我的目的不是锁数据。。就是感觉这样应该也能执行的。。。
    郑州-司令(117838621) 20:28:11
    可是,当我app调用两次的时候,竟然死机。。
    雄哥(309683352) 20:28:14
    自旋锁不会挂起,不会交出cpu的使用权,只会一直在那让cpu空转
    雄哥(309683352) 20:28:27
    相当于while (1
    雄哥(309683352) 20:28:42
    建议你用信号量
    郑州-司令(117838621) 20:29:04
    信信号量我懂,可是一直不理解这个自旋锁
    郑州-司令(117838621) 20:29:05
    比如说:
    spin_lock(&spin);
    //临界资源访问
    globalvar_count++;
    spin_unlock(&spin);

    雄哥(309683352) 20:29:26
    自旋锁就相当于while(1
    雄哥(309683352) 20:29:39
    直到条件满足才会往下执行
    郑州-司令(117838621) 20:29:43
    我又两个app,第一个spin_lock(&spin); 得到了,开始 globalvar_count++; 此时第二个又来了。。该当如何
    雄哥(309683352) 20:30:08
    那他就会永远执行自旋锁
    郑州-司令(117838621) 20:30:19
    那么第二个是不是因为得不到锁而占用cpu100%使用权
    郑州-司令(117838621) 20:30:25
    那么第一个还怎么执行呀
    雄哥(309683352) 20:30:33
    第一个不会执行了
    雄哥(309683352) 20:30:53
    除非是多cpu机器
    郑州-司令(117838621) 20:31:07
    那么这段代码是不是有问题呀。。
    雄哥(309683352) 20:31:10
    自旋的意思就是一直在那不停的旋转
    雄哥(309683352) 20:31:18
    不会挂起,不会释放
    郑州-司令(117838621) 20:31:33
    是app自锁,还是内核自锁。。。
    郑州-司令(117838621) 20:31:42
    就是是哪个占用了100%
    郑州-司令(117838621) 20:32:08
    不过,熊哥,这段代码很常见:
    spin_lock(&spin);
    //临界资源访问
    globalvar_count++;
    spin_unlock(&spin);
    雄哥(309683352) 20:32:30
    怎么会有用户的东西啊,执行open系统调用,肯定已经陷入内核了
    郑州-司令(117838621) 20:32:33
    如果是系统死掉的话,岂不,内核源码会有问题
    郑州-司令(117838621) 20:33:03
    哦,也就是说一旦自旋锁锁住了,系统也就挂了。。。

    雄哥(309683352) 20:33:03
    这个一般是用非阻塞的形式
    郑州-司令(117838621) 20:33:37
    信号量和自旋锁不是处理并发控制么?
    雄哥(309683352) 20:33:53
    多cpu的情况下一般用自旋锁
    郑州-司令(117838621) 20:33:59
    那么如果用自旋锁的话,该如何写呀。。
    雄哥(309683352) 20:34:01
    比如你是双核的cpu
    郑州-司令(117838621) 20:34:04
    哦,多cpu
    郑州-司令(117838621) 20:34:22
    也就是说如果是单核的话,基本上不用自旋锁了。。。
    雄哥(309683352) 20:34:25
    一个cpu锁住了,还可以由别的cpu解锁
    雄哥(309683352) 20:34:50
    单核可抢占内核也可以用自旋锁
    雄哥(309683352) 20:34:59
    但是一般用非阻塞形式
    雄哥(309683352) 20:35:17
    而且中断下半段或是中断上下文中用
    郑州-司令(117838621) 20:35:35
    可抢占内核,岂不linux不行了。。。
    雄哥(309683352) 20:35:37
    因为中断不能被挂起,所以不能用信号量
    郑州-司令(117838621) 20:35:48

    雄哥(309683352) 20:35:51
    linux 2.6以后就是可抢占了
    郑州-司令(117838621) 20:36:13
    哦,也就是说我上面这段代码也是可以用的了。。。
    雄哥(309683352) 20:36:51
    不行啊
    雄哥(309683352) 20:37:10
    你不是在中断上下文中,而是在进程上下文中
    郑州-司令(117838621) 20:37:45
    熊哥:还是这个:
    我又两个app,第一个spin_lock(&spin); 得到了,开始 globalvar_count++; 此时第二个又来了。。该当如何

    我在我机器上试了一下,这时第一个还是可以执行的。。。
    郑州-司令(117838621) 20:38:13
    不过我的代码不是这个样子
    郑州-司令(117838621) 20:38:50
    是这个样子:
    static int globalvar_open(struct inode *inode, struct file *filp)
    {
    //获得自旋锁
    spin_lock(&spin);
    //临界资源访问
    printk("got the spin\n");
    if (globalvar_count)
    {
    spin_unlock(&spin);
    return - EBUSY;
    }
    globalvar_count++;
    //释放自旋锁
    spin_unlock(&spin);
    return 0;
    }

    /*因为设备打开后,如果没有执行 读写操作,应用层的close(fd)就没 执行,globalvar_count的值不变
    只有应用层读写完以后,才进行
    */
    static int globalvar_release(struct inode *inode, struct file *filp)
    {
    globalvar_count--;
    return 0;
    }

    郑州-司令(117838621) 20:39:14
    这是我看《linux设备驱动开发入门》照着上面做的。。。
    雄哥(309683352) 20:39:44
    spin_trylock
    雄哥(309683352) 20:40:00
    用这个获得自旋锁,就不会锁死
    郑州-司令(117838621) 20:40:08

    郑州-司令(117838621) 20:40:12
    这个呀
    郑州-司令(117838621) 20:40:16
    好的。。
    郑州-司令(117838621) 20:41:13
    好的,我记下了。。。
    雄哥(309683352) 20:41:24
    返回非0表示成功获得了锁,返回0表示没有获得锁
    郑州-司令(117838621) 20:41:36
    哦,好
    风清雾明(779804667)  20:46:40
    如果当前的CPU持有自旋锁时,是不允许进入睡眠的。
    风清雾明(779804667) 20:46:59
    LDD3上有详细论述。
    郑州-司令(117838621) 20:48:13

    郑州-司令(117838621) 20:48:38
    spin_lock(&spin);
    //临界资源访问
    globalvar_count++;
    spin_unlock(&spin);
    郑州-司令(117838621) 20:49:58
    应该说是第一个app进程持有了,而第二个app进程又来了。。因而导致第二个一直100%,那么第一个岂不一点也不能执行了。。
    风清雾明(779804667) 20:50:00
    也就是说当第一个在运行并持有自旋锁时,该CPU不会被调度出去。而别的CPU运行第二个时,会停在原地等待另一个CPU释放自旋锁。
    郑州-司令(117838621) 20:52:28
    哦,这是从2个cpu角度来说明的,呵呵
    郑州-司令(117838621) 20:52:35
    这个我理解了。。
    郑州-司令(117838621) 20:52:53
    不过如果单核的话,就是系统死掉了。。。
    郑州-司令(117838621) 20:54:18
    也就是说,一般如果是单核的话,基本上不要使用自旋锁,是么?
    郑州-司令(117838621) 20:54:23
    风清雾明(779804667),,还在么?
    风清雾明(779804667) 20:58:15
    司令  20:55:32
    风清哥。。。
    司令 20:55:35
    在么?
    风清雾明 20:55:52

    司令 20:56:08
    就是我刚才在群里面文的问题。。。
    风清雾明 20:56:10
    自己上网一搜,全是。
    风清雾明 20:56:20
    http://topic.csdn.net/u/20100909/18/79787565-7b1a-404b-97f7-44b9f81319d3.html
    司令 20:56:36
    哦,好,我看看

    有关单核非抢占式内核的自旋锁问题
    http://topic.csdn.net/u/20100909/18/79787565-7b1a-404b-97f7-44b9f81319d3.html
    郑州-司令(117838621) 20:58:59
    好的,谢谢了,小弟有点开窍了。。。
    风清雾明(779804667) 20:59:37
    不客气。上网搜资料是成长的必要途径。
    郑州-司令(117838621) 20:59:51
    哦,对
    
    

    到最后也真有点明白,咳,记录下来吧。。。

    http://topic.csdn.net/u/20100909/18/79787565-7b1a-404b-97f7-44b9f81319d3.html这个页面讲的也可以,也就说是如果是单核的话,在编译的时候系统自动把自旋锁给去掉了。



  • 相关阅读:
    memmove、memccpy和memcpy
    NSLocalizedString不起作用
    sign starfieldtech
    微软推荐的Get a code signing certificate流程和链接
    Driver Signing changes in Windows 10
    delphi 打开文件夹并定位到一个文件(关键是/select参数)
    key转成pvf
    nginx+apache+mysql+php+memcache+squid搭建集群web环境
    dddd
    Delphi系统变量:IsMultiThread对MM的影响
  • 原文地址:https://www.cnblogs.com/fishoneseaatblog/p/2361887.html
Copyright © 2011-2022 走看看