2015-01-13 129 views
0

我已經在內核模塊中使用kthread_run創建了一個內核線程。 線程非常簡單,就像波紋管一樣。爲什麼Linux內核線程會佔用cpu

static int my_thread_func(void * data) 
{ 
    int a; 
    DBG_PRINT("policy:%lu; prio:%d", current->policy, current->prio); 
    while (!kthread_should_stop()) 
    { 
     a++; 
    } 
} 

但是,在我加載模塊後,系統沒有再響應。

所以我想知道這個內核線程的調度策略和優先級是什麼。 然後我試着打印出這個內核線程的調度策略和優先級, 並得到了波紋管輸出。

policy:0; prio:120

policy:0表示SCHED_NORMAL;
prio:120這個數字也不高。

雖然線程沒有SCHED_FIFO或SCHED_RR調度策略,但它爲什麼會佔用cpu?

而且我還發現,如果我在線程的循環體中插入了一些睡眠代碼,系統可以保持響應。

而且我還發現,當我運行一個用戶空間程序實現爲波紋管時,系統也保持了響應。

int main(int argc, char *argv[]) 
{ 
    int a; 
    while (1) a++; 
    return 0; 
} 

那麼誰能告訴我,爲什麼內核線程可能會佔用cpu。

+0

你的內核線程永遠不會產生控制權('wait_event_interruptible'和好友),所以它當然會阻止事件被處理。它也不處理信號。 –

+0

但內核線程的調度策略是SCHED_NORMAL,而不是SCHED_FIFO或SCHED_RR,所以一旦內核線程耗盡了它的時間片,其他任務就有機會運行。 – sunmingbao

+0

只有當你正在對內核進行控制時,你不是。 –

回答

0

當您說優先級爲120時,您是否注意到kthreadd的優先級或爲您創建的實際內核線程?

請參閱http://lxr.free-electrons.com/source/kernel/kthread.c#L310瞭解用於創建新內核線程的函數。

摘錄:

struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), 
              void *data, int node, 
              const char namefmt[], 
              ...) 
{ 
    ... 
     if (!IS_ERR(task)) { 
       static const struct sched_param param = { .sched_priority = 0 }; 
       ... 
       /* 
       * root may have changed our (kthreadd's) priority or CPU mask. 
       * The kernel thread should not inherit these properties. 
       */ 
       sched_setscheduler_nocheck(task, SCHED_NORMAL, &param); 
       set_cpus_allowed_ptr(task, cpu_all_mask); 
     } 
    ... 
} 

看來,sched_priority設置爲0。現在

,請看看http://lxr.free-electrons.com/source/include/linux/sched/prio.h#L9

摘錄:

/* 
* Priority of a process goes from 0..MAX_PRIO-1, valid RT 
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH 
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority 
* values are inverted: lower p->prio value means higher priority. 
* 
* The MAX_USER_RT_PRIO value allows the actual maximum 
* RT priority to be separate from the value exported to 
* user-space. This allows kernel threads to set their 
* priority to a value higher than any user task. Note: 
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. 
*/ 

請注意第二段:This allows kernel threads to set their priority to a value higher than any user task.

摘要:

看來,新創建的內核線程設置到sched_priority0即使有SCHED_NORMAL0的優先級不是SCHED_NORMAL的正常優先級,因此內核線程將優先於任何其他線程(即不使用RT策略---並且我認爲內核中的任何進程默認使用RT )。

附錄:

注:我不是100%肯定,如果是這樣的原因。但是,如果你看一下在內核爲內核線程的評論,它們似乎都暗示着一個內核線程保持運行,除非:

  • 內核線程本身讓步或來電do_exit
  • 別人打電話給kthread_should_stop()

對我來說,聽起來像內核線程只要它想要,直到它決定停止,或者別人明確地告訴它停止。