免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5486 | 回复: 12
打印 上一主题 下一主题

2.6.24的内核是可抢占的吗?(已解决) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-25 14:01 |只看该作者 |倒序浏览
我让一个进程获得了自旋锁,然后执行schedule_timeout休眠10s(只是测试),之后再释放自旋锁;接着另外一个进程又想获得这个自旋锁,接着就死机了.如果内核是随处都可以抢占的话,是不应该死机的.

请教高手,不是说2.6的内核已经可以抢占了,是不是我用的内核版本编译的不对?

[ 本帖最后由 ryancat 于 2008-9-27 11:00 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-09-26 20:49 |只看该作者
单处理器上,自旋锁不能用在中断,睡眠中

论坛徽章:
0
3 [报告]
发表于 2008-09-26 21:39 |只看该作者
原帖由 eveson 于 2008-9-26 20:49 发表
单处理器上,自旋锁不能用在中断,睡眠中

是的,我这里是做个测试,看内核是否随处都可以抢占.
对这样的结果还是不能理解,如果真的是可抢占内核的话.

论坛徽章:
0
4 [报告]
发表于 2008-09-26 23:24 |只看该作者
对于标题,回答是肯定的
对于你说的内容,我觉得你对自旋锁没理解。自旋锁本身就用来禁止抢占的。你在临界区(获得自旋锁的代码区)内睡眠,又没中断打断,不死才怪

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
5 [报告]
发表于 2008-09-27 09:47 |只看该作者
原帖由 sep 于 2008-9-26 23:24 发表
对于标题,回答是肯定的
对于你说的内容,我觉得你对自旋锁没理解。自旋锁本身就用来禁止抢占的。你在临界区(获得自旋锁的代码区)内睡眠,又没中断打断,不死才怪


有道理!

论坛徽章:
0
6 [报告]
发表于 2008-09-27 09:59 |只看该作者
原帖由 sep 于 2008-9-26 23:24 发表
对于标题,回答是肯定的
对于你说的内容,我觉得你对自旋锁没理解。自旋锁本身就用来禁止抢占的。你在临界区(获得自旋锁的代码区)内睡眠,又没中断打断,不死才怪

是这样的,我知道获得了自旋锁后不能休眠,但是我这里这样写的目的是验证内核是否可以抢占,这段代码的流程是这样的:
1. 获得自旋锁
2. 休眠10s并调度
3. 释放自旋锁
当只有一个进程执行这段代码的时候,是不会死机的,从调试信息看,10s后确实释放了自旋锁.
但是当一个进程执行了这段代码,然后我又新启一个进程执行这段代码的时候,就系统死机了.
我认为,如果内核是随处可抢占,而不是只在某些关键点可以抢占的话,第2个进程当无法获取自旋锁,自旋一段时候后会再次调度前一个进程执行,就释放掉了自旋锁,系统就不会死机.
所以我觉得这个内核不是像真正的实时系统一样是完全可以抢占的.
代码如下:
ssize_t spin_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos)
{
        struct spin_dev *dev = filp->private_data;
        int delay = 10;

        printk(KERN_EMERG"process %i(%s) call %s\n", current->pid, current->comm, __FUNCTION__);
        spin_lock_irq(&dev->spinlock);
        printk(KERN_EMERG"process %i(%s) get spinlock\n", current->pid, current->comm);
        printk(KERN_EMERG"process %i(%s) begin to wait %i seconds\n", current->pid, current->comm, delay);
        set_current_state(TASK_INTERRUPTIBLE);
        schedule_timeout(delay * HZ);
        spin_unlock_irq(&dev->spinlock);
        printk(KERN_EMERG"process %i(%s) release spinlock\n", current->pid, current->comm);

        return count;
}

[ 本帖最后由 ryancat 于 2008-9-27 10:01 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-09-27 10:17 |只看该作者
我印象中spin_lock主要是用于多处理器的吧,实际上是一个循环死等吧。以前Linux都是专门编译SMP版本和非SMP版本的,现在许多发行商图省事好像直接发面的是SMP版本的;当然就算是多核,你这种用法还是有可能最终全部挂死的。

我感觉你对内核“可抢占”的理解有问题,任何系统中,不管怎么设计,但终都会有一部分必须是串行执行的,所谓“可抢占”只是这一部分要尽量小而已,Linux内核的可抢占性是指它进入内核态之后许多时候还是可以被抢占的,并不是在内核的任何执行过程中都能被抢占。你见过哪一个实时操作系统可以在任何时候可以被抢占吗?VxWorks有一个kernel state,一旦进入这个状态任何抢占后最终也需要在kernel state执行的操作都会被挂在一个work queue中,最终串行地执行。

论坛徽章:
0
8 [报告]
发表于 2008-09-27 10:59 |只看该作者
原帖由 Cyberman.Wu 于 2008-9-27 10:17 发表
我印象中spin_lock主要是用于多处理器的吧,实际上是一个循环死等吧。以前Linux都是专门编译SMP版本和非SMP版本的,现在许多发行商图省事好像直接发面的是SMP版本的;当然就算是多核,你这种用法还是有可能最终 ...

我找到可能的原因了,在单核上面获取自旋锁一般就是关调度,这个时候其他进程就没法抢占了,所以死机.

论坛徽章:
0
9 [报告]
发表于 2008-09-28 10:20 |只看该作者

回复 #8 ryancat 的帖子

Linux不清楚,不过一般来说CPU总要干点什么的,关调度并不见得就不能切换。

对于单核,由于同一时刻只有一个任务在招待,所以切换的时机也内有两个,一是当前任务通过调用进入内核空间引起主动切换,另一个是外部中断(包含时钟中断)而导致的切换,所以如果一个任务如果持有信号量而切换出去,后面任务还会继续运行,如果它也去获取这个信号量,就会由于获取失败而也切换出去。而对于spin lock,实际上主动是用于多CPU之前互斥的,由于是非常短的操作,通常就用“忙等”了吧。下面是2.6.9内核中i386的实现:


static inline void _raw_spin_lock(spinlock_t *lock)
{
#ifdef CONFIG_DEBUG_SPINLOCK
        if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
                printk("eip: %p\n", __builtin_return_address(0));
                BUG();
        }
#endif
        __asm__ __volatile__(
                spin_lock_string
                :"=m" (lock->lock) : : "memory");
}

#define spin_lock_string \
        "\n1:\t" \
        "lock ; decb %0\n\t" \
        "jns 3f\n" \
        "2:\t" \
        "rep;nop\n\t" \
        "cmpb $0,%0\n\t" \
        "jle 2b\n\t" \
        "jmp 1b\n" \
        "3:\n\t"

从这里可以看出是一个死循环,只到变量恢复为1为止。

如果只是想锁一下如果不行就不做某种操作应该用spin_trylock吧。另外Linux内核中如果不打开SMP开关编译实际上spin_lock是空操作,就不会出现这种情况了;不过现在的发行版本如果不自己重新编译内核都是直接支持SMP的,主要是现在多核的CPU越来越多,而对于普通用户要编译内核也是很麻烦的。

[ 本帖最后由 Cyberman.Wu 于 2008-9-28 11:02 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2008-09-28 13:23 |只看该作者

回复 #1 ryancat 的帖子

对的 2.6肯定是可以抢占的
但是自旋锁是不可中断的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP