乍一看,我的问题看起来可能有点微不足道。 请多多包涵,并完整地阅读。
我在Linux内核模块确定一个繁忙的循环。 由于这一点,其他处理(例如sshd的)没有得到CPU时间的时间(如20秒)长跨距。 这是可以理解我的机器只有一个CPU和繁忙的循环是不给机会调度其他进程。
只是为了实验,我曾在繁忙的循环每次迭代后增加的时间表()。 即便如此,这将是保持CPU繁忙,但仍应该让其他进程运行,因为我调用schedule()。 但是,这似乎并没有发生。 我的用户级进程仍然挂的时间跨度长(20秒)。
在这种情况下,内核线程得到了很好的价值-5和用户级线程得到了很好的值为0即使用户级线程的优先级低,我觉得20秒太长得不到CPU。
是否有人可以解释为什么这可能是发生?
注:我知道如何完全删除忙循环。 但是,我想在这里了解内核的行为。 内核版本2.6.18是和内核抢占被禁止。
该schedule()
函数简单地调用调度-它没有采取任何特别措施,安排调用线程将被另一个所代替。 如果当前线程仍然在运行队列优先级最高的一个,然后它会被调度再次进行选择。
这听起来好像你的内核线程正在做的工作很少在繁忙的循环,它调用schedule()
每次轮。 因此,它可能不使用的CPU时间本身,因此不具有其优先级大大降低。 负nice值进行比阳性重量较重,所以-5和0之间的差别还是比较明显的。 这两种效应的结合意味着我不会太惊讶,用户空间进程错过。
作为一个实验,你可以尝试调用调度循环的每第N个迭代(你将不得不尝试着去找到N个针对您的平台一个很好的价值),看看情况较好-调用schedule()
往往会浪费很多在调度CPU时间。 当然,这只是一个实验-因为你已经指出的那样,避免空循环是在生产代码正确的选项,如果你想确保你的线程被另一个取代,然后将其设置为TASK_INTERRUPTIBLE
调用之前schedule()
到远程本身从运行队列(如已经在注释中提到的)。
请注意,你的内核(2.6.18)使用Ø其存在,直到(1)调度完全公平调度器是在2.6.23(将O一)在2.6中添加(调度加入到更换更老的为O(n )调度 )。 食物安全中心不使用运行队列和以不同的方式工作,所以你可能会看到不同的行为 - 我与它不太熟悉,不过,所以我不喜欢预测你会看到什么区别。 我已经看够的是要知道,“完全公平”是不是我就必须在重负载SMP系统有大量双核和流程的名词,但我也接受,编写调度是一个非常棘手的任务和它的远离我见过最差的,我从来没有遇到过显著问题,它的核心4-8台式机上。
文章来源: Why processes are deprived of CPU for TOO long while busy looping in Linux kernel?