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

北京-司令(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这个页面讲的也可以,也就说是如果是单核的话,在编译的时候系统自动把自旋锁给去掉了。



分类:

技术点:

相关文章: