分析linux核心的idle的知識

來源:互聯網
上載者:User

      Linux系統越來越受到電腦使用者的歡迎,於是很多人開始學習Linux時,學習linux,你可能會遇到linux核心問題,這裡將介紹linux核心中idle知識,在這裡拿出來和大家分享一下。

  1. idle是什麼

  簡單的說idle是一個進程,其pid號為0。其前身是系統建立的第一個進程,也是唯一一個沒有通過fork()產生的進程。在smp系統中,每個處理器單元有獨立的一個運行隊列,而每個運行隊列上又有一個idle進程,即有多少處理器單元,就有多少idle進程。系統的空閑時間,其實就是指idle進程的"已耗用時間"。既然是idle是進程,那我們來看看idle是如何被建立,又具體做了哪些事情?

  2. idle的建立

  我們知道系統是從BIOS加電自檢,載入MBR中的引導程式(LILO/GRUB),再載入linux核心開始啟動並執行,一直到指定shell開始運行告一段落,這時使用者開始操作Linux。而大致是在vmlinux的入口startup_32(head.S)中為pid號為0的原始進程設定了執行環境,然後原是進程開始執行start_kernel()完成Linux核心的初始化工作。包括初始化頁表,初始化中斷向量表,初始化系統時間等。繼而調用 fork(),建立第一個使用者進程:

  kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

  這個進程就是著名的pid為1的init進程,它會繼續完成剩下的初始化工作,然後execve(/sbin/init), 成為系統中的其他所有進程的祖先。關於init我們這次先不研究,回過頭來看pid=0的進程,在建立了init進程後,pid=0的進程調用 cpu_idle()演變成了idle進程。

  current_thread_info()->status |= TS_POLLING;

  在 smp系統中,除了上面剛才我們講的主處理器(執行初始化工作的處理器)上idle進程的建立,還有從處理器(被主處理器activate的處理器)上的 idle進程,他們又是怎麼建立的呢?接著看init進程,init在演變成/sbin/init之前,會執行一部分初始化工作,其中一個就是 smp_prepare_cpus(),初始化SMP處理器,在這過程中會在處理每個從處理器時調用

  task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);

  init_idle(task, cpu);

  即從init中複製出一個進程,並把它初始化為idle進程(pid仍然為0)。從處理器上的idle進程會進行一些Activate工作,然後執行cpu_idle()。

  整個過程簡單的說就是,原始進程(pid=0)建立init進程(pid=1),然後演化成idle進程(pid=0)。init進程為每個從處理器(運行隊列)建立出一個idle進程(pid=0),然後演化成/sbin/init。

  3. idle的運行時機

  idle 進程優先順序為MAX_PRIO,即最低優先順序。早先版本中,idle是參與調度的,所以將其優先順序設為最低,當沒有其他進程可以運行時,才會調度執行 idle。而目前的版本中idle並不在運行隊列中參與調度,而是在運行隊列結構中含idle指標,指向idle進程,在調度器發現運行隊列為空白的時候運行,調入運行。

  4. idle的workload

  從上面的分析我們可以看出,idle在系統沒有其他就緒的進程可執行檔時候才會被調度。不管是主處理器,還是從處理器,最後都是執行的cpu_idle()函數。所以我們來看看cpu_idle做了什麼事情。

  因為idle進程中並不執行什麼有意義的任務,所以通常考慮的是兩點:1.節能,2.低退出延遲。

  其核心代碼如下:

  void cpu_idle(void)  {   int cpu = smp_processor_id();    current_thread_info()->status |= TS_POLLING;    /* endless idle loop with no priority at all */   while (1) {     tick_nohz_stop_sched_tick(1);     while (!need_resched()) {       check_pgt_cache();      rmb();       if (rcu_pending(cpu))       rcu_check_callbacks(cpu, 0);       if (cpu_is_offline(cpu))       play_dead();       local_irq_disable();      __get_cpu_var(irq_stat).idle_timestamp = jiffies;      /* Don't trace irqs off for idle */      stop_critical_timings();      pm_idle();      start_critical_timings();     }     tick_nohz_restart_sched_tick();     preempt_enable_no_resched();     schedule();     preempt_disable();   }  }

  迴圈判斷need_resched以降低退出延遲,用idle()來節能。

  預設的idle實現是hlt指令,hlt指令使CPU處於暫停狀態,等待硬體中斷髮生的時候恢複,從而達到節能的目的。即從處理器C0態變到 C1態(見 ACPI標準)。這也是早些年windows平台上各種"處理器降溫"工具的主要手段。當然idle也可以是在別的ACPI或者APM模組中定義的,甚至是自訂的一個idle(比如說nop)。

  小結:

  1.idle是一個進程,其pid為0。

  2.主處理器上的idle由原始進程(pid=0)演變而來。從處理器上的idle由init進程fork得到,但是它們的pid都為0。

  3.Idle進程為最低優先順序,且不參與調度,只是在運行隊列為空白的時候才被調度。

  4.Idle迴圈等待need_resched置位。預設使用hlt節能。

  希望通過本文你能全面瞭解linux核心中idle知識。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.