我的用户空间进程运行时调度策略为SCHED_OTHER(0),优先级为120(默认优先级,top表示PR为20)。它运行一个无限的while(1)循环,没有任何系统调用或等待等。它与特定的CPU相关,比如1.
在内核空间中,我有一个内核线程,它也是使用默认调度参数(策略:SCHED_NORMAL(0)和优先级120)创建的。它进入睡眠状态,调用wait_event_interruptible()。以1ms的周期发生的irq线程唤醒内核线程。内核线程没有绑定到任何CPU。
如果内核线程在与用户空间进程相同的CPU上进行调度,则在唤醒调用完成后它不会被唤醒。如果内核线程在其他免费的CPU上进行调度,它就会被唤醒。只有当内核定时器中断发生且ksoftirq线程被调度并且在退出时它才会调度内核线程。因此,内核线程不会像预期的那样在1ms内唤醒一次。
我希望通过抢占用户空间进程来唤醒内核线程。那没有发生。有人可以帮助我解决这里发生的事情吗?
顺便说一句,如果我将内核线程的调度更改为SCHED_FIFO并给出RT优先级,它可以正常工作。答案 0 :(得分:0)
我希望通过抢占用户空间进程来唤醒内核线程。有人可以帮助我解决这里发生的事情吗?
首先,SCHED_OTHER
是SCHED_NORMAL
的别名。其次,调度程序不区分内核和用户空间线程(除非通过CGroup进行分层调度)。
唯一允许睡眠者线程抢占CPU绑定线程的机会是,如果它花费在CPU上的时间较短(通过vruntime
跟踪),但是1ms似乎是太小的间隔来实现这个效果重要的,即在CFS中计算时间片的基础是6ms(sysctl_sched_latency
)。
您可能会尝试使用cfstrace.stp脚本(需要SystemTap)来跟踪调度程序状态并尝试理解这种情况发生的原因(它将转储CFS的内部状态,包括vruntime
值)。
我将内核线程的调度更改为SCHED_FIFO并赋予RT优先级,它工作正常。
是的,如果您需要“实时”,则需要使用SCHED_FIFO
或SCHED_DEADLINE