为什么进程在Linux内核繁忙的循环中长时间被剥夺了CPU?

前端之家收集整理的这篇文章主要介绍了为什么进程在Linux内核繁忙的循环中长时间被剥夺了CPU?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
乍一看,我的问题可能看起来有些微不足道.请忍受我,并完全阅读.

我在Linux内核模块中确定了一个繁忙的循环.因此,其他进程(例如sshd)在长时间(如20秒)内没有获得cpu时间.这是可以理解的,因为我的机器只有单个cpu,而忙环没有机会安排其他进程.

只是为了实验,我在忙碌的循环中每次迭代后添加了schedule().即使这样做会使cpu处于繁忙状态,但是它仍然会让其他进程运行,因为我正在调用schedule().但是,这似乎并没有发生.我的用户级别进程长时间悬停(20秒).

在这种情况下,内核线程得到不错的值-5,用户级别线程得到很好的值0.即使用户级别线程的优先级低,我认为20秒太长,不能得到cpu.

有人可以解释为什么会发生这种情况吗?

注意:我知道如何彻底清除繁忙的循环.但是,我想在这里了解内核的行为.内核版本为2.6.18,内核抢占功能被禁用.

解决方法

schedule()函数简单地调用调度程序 – 它不采取任何特殊的措施来安排调用线程被替换为不同的调用线程.如果当前线程仍然是运行队列中的最高优先级,那么它将再次由调度程序选择.

听起来好像你的内核线程在繁忙的循环中做的很少,每次都调用schedule().因此,它本身可能没有使用太多的cpu时间,因此没有将其优先级降低很多.负的漂亮值比正面值更重,所以-5和0之间的差异是相当明显的.这两个效果的结合意味着我不会惊讶于用户空间进程错过了.

作为一个实验,您可以尝试在循环的第N次迭代中调用调度器(您必须尝试为您的平台找到N的良好值),并查看情况是否更好 – 调用schedule()太频繁,将浪费调度程序中有大量cpu时间.当然,这只是一个实验 – 正如你已经指出的那样,避免繁忙的循环是生产代码中的正确选项,如果你想确保你的线程被另一个替换,然后在调用schedule之前将其设置为TASK_INTERRUPTIBLE )从运行队列远程本身(如在注释中已经提到的).

请注意,您的内核(2.6.18)正在使用存在的O(1)调度程序,直到在2.6.23中添加Completely Fair Scheduler(在2.6中添加了O(1)调度程序以替换较旧的O(n) scheduler). CFS不使用运行队列并以不同的方式工作,所以您可能会看到不同的行为 – 但我不太熟悉,所以我不想准确地预测你会看到什么差异.我已经看到足够的知道,“完全公平”不是我在大量的核心和进程的大量加载的SMP系统上使用的术语,但是我也接受写一个调度器是一个非常棘手的任务,远远不及我见过的最糟糕的一面,而我在4-8核心台式机上从未遇到过重大问题.

原文链接:https://www.f2er.com/linux/393680.html

猜你在找的Linux相关文章