1. 程式人生 > >Linux程序和核心級程序的一些知識

Linux程序和核心級程序的一些知識

理想情況下,您應該明白在您的系統中執行的每一個程序。要獲得所有程序的列表,可以執行命令ps -ef(POSIX 風格)或 ps ax(BSD 風格)。程序名有方括號的是核心級的程序,執行輔助功能(比如將快取寫入到磁碟);所有其他程序都是使用者程序。您會注意到,就算是在您新安裝的(最小化的)系統中,也會有很多程序在執行。熟悉它們,並把它們記錄到文件中。

1.kswapd0

Linux uses kswapd for virtual memory management such that pages that have been recently accessed are kept in memory and less active pages are paged out to disk.
(what is a page?)…Linux uses manages memory in units called pages.
So,the kswapd 

process regularly decreases the ages of unreferenced pages…and at the end they are paged out(moved out) to disk

系統每過一定時間就會喚醒kswapd,看看記憶體是否緊張,如果不緊張,則睡眠,在kswapd中,有2個閥值,pages_hige和pages_low,當空閒記憶體頁的數量低於pages_low的時候,kswapd程序就會掃描記憶體並且每次釋放出32個free pages,直到free page的數量到達pages_high.

2.kjournald

EXT3檔案系統的日誌程序,具有3種模式:

journal – logs all filesystem data and metadata changes. The slowest of the three ext3 journaling modes, this journaling mode minimizes the chance of losing the changes you have made to any file in an ext3 filesystem.(記錄所有檔案系統上的元資料改變,最慢的一種模式,)

ordered – only logs changes to filesystem metadata, but flushes file data updates to disk before making changes to associated filesystem metadata. This is the default ext3 journaling mode.(預設使用的模式,只記錄檔案系統改變的元資料,並在改變之前記錄日誌)

writeback – only logs changes to filesystem metadata but relies on the standard filesystem write process to write file data changes to disk. This is the fastest ext3 journaling mode.(最快的一種模式,同樣只記錄修改過的元資料,依賴標準檔案系統寫程序將資料寫到硬碟)

修改模式EXT3的工作模式;

vim /etc/fstab

/dev/hda5      /opt            ext3       data=writeback        1 0
詳細介紹:http://www.linuxplanet.com/linuxplanet/reports/4136/5/


3、pdflush


pdflush用於將記憶體中的內容和檔案系統進行同步,比如說,當一個檔案在記憶體中進行修改,pdflush負責將它寫回硬碟.每當記憶體中的垃圾頁(dirty page)超過10%的時候,pdflush就會將這些頁面備份回硬碟.這個比率是可調節的,通過/etc/sysctl.conf中的 vm.dirty_background_ratio項 預設值為10 也可以

cat /proc/sys/vm/dirty_background_ratio 檢視當前的值

4、kblockd —- 塊讀寫子系統

什麼是程序遷移?
程序遷移就是將一個程序從當前位置移動到指定的處理器上。它的基本思想是在程序執行過程中移動它,使得它在另一個計算機上繼續存取它的所有資源並繼續執行,而且不必知道執行程序或任何與其它相互作用的程序的知識就可以啟動程序遷移操作,這意味著遷移是透明的。
程序遷移的好處
程序遷移是支援負載平衡和高容錯性的一種非常有效的手段。對一系列的負載平衡策略的研究表明程序遷移是實現負載平衡的基礎,程序遷移在很多方面具有適用性:

動態負載平衡:將程序遷移到負載輕或空閒的節點上,充分利用可用資源,通過減少節點間負載的差異來全面提高效能。 
容錯性和高可用性:某節點出現故障時,通過將程序遷移到其它節點繼續恢復執行,這將極大的提高系統的可靠性和可用性。在某些關鍵性應用中,這一點尤為重要。 
並行檔案IO:將程序遷移到檔案伺服器上進行IO,而不是通過傳統的從檔案伺服器通過網路將資料傳輸給程序。對於那些需向檔案伺服器請求大量資料的程序,這將有效的減少了通訊量,極大的提高效率。

 
充分利用特殊資源:程序可以通過遷移來利用某節點上獨特的硬體或軟體能力。

 
記憶體導引(Memory Ushering)機制:當一個節點耗盡它的主存時,Memory Ushering機制將允許程序遷移到其它擁有空閒記憶體的節點,而不是讓該節點頻繁地進行分頁或和外存進行交換。這種方式適合於負載較為均衡,但記憶體使用存在差異或記憶體物理配置存在差異的系統。 
程序遷移的實現角度
程序遷移的實現複雜性及對OS的依賴性阻礙了程序遷移的廣泛使用 ,尤其是對透明的程序遷移實現。根據應用的級別,程序遷移可以作為OS的一部分、使用者空間、系統環境的一部分或者成為應用程式的一部分。

使用者級遷移:使用者級實現較為簡單,軟體開發和維護也較為容易,因此,現有的很多系統都是採用使用者級實現,如Condor和Utopia。但由於在使用者級無法獲得Kernel的所有狀態,因此,對於某類程序,無法進行遷移。另外,由於Kernel空間和User空間之間存在著壁壘,打破這個邊界獲得 Kernel提供的服務需要巨大的開銷。因此,使用者級實現效率遠遠低於核心級實現。 
應用級遷移:應用級遷移實現較為簡單,可移植性好,但是需要了解應用程式語義並可能需對應用程式進行修改或重編譯,透明性較差,這方面的系統有Freedman、Skordos等。 
核心級遷移:基於核心的實現可以充分利用OS提供的功能,全面的獲取程序和OS狀態,因此實現效率較高,能夠為使用者提供很好的透明性。但是由於需要對OS進行修改,實現較為複雜。這方面的典型系統有MOSIX和 Sprite系統。

程序狀態
程序遷移的主要工作就在於提取程序狀態,然後在目的節點根據程序狀態再生該程序。在現實中,一個程序擁有很多狀態,並且隨著作業系統的演化,程序狀態也越來越多樣。一般來說,一個程序的狀態可以分為以下幾類:

程序執行狀態(Execution State):表示當前執行程序的處理器狀態,和機器高度相關。包括核心在上下文切換時儲存和恢復的資訊,如通用和浮點暫存器值、棧指標、條件碼等。 
程序控制(Process Control):作業系統系統用來控制程序的所有信,一般包括程序優先順序、程序標識,父程序標識等。一旦系統編排了程序控制資訊,程序遷移系統必須凍結該程序的執行。 
程序Memory狀態和程序地址空間:包括程序的所有虛存資訊,程序資料和程序的堆疊資訊等,是程序狀態的最主要的一部分。 
程序的訊息(Message)狀態:包括程序緩衝的訊息和連線(Link)的控制資訊。程序遷移中通訊連線的保持以及遷移後連線的恢復是程序遷移中一項較有挑戰意義的問題。 
檔案狀態:程序的檔案狀態包括檔案描述符和檔案緩衝快。保持檔案的Cache一致性和程序間檔案同步訪問也是程序遷移機制需要著重考慮的。 
由於在同構的環境下(相同或相容的機器體系結構和指令集以及作業系統)提取和恢復程序狀態相對容易,現有的工作大多是以同構環境為前提的。不過,越來越多的人開始研究異構環境下的程序遷移機制,如TUI 系統。

#ps  相關程序  (k開頭的基本上都是核心驅動,不建議殺掉)

PID TTY      STAT    TIME COMMAND
1    ?        Ss     0:00 init [3]                 (引導使用者空間服務,管理孤兒執行緒,不能殺)     
2    ?        S      0:00 [migration/0]
3    ?        SN     0:00 [ksoftirqd/0]            (核心排程/管理第0個CPU軟中斷的守護程序,不能殺)
4    ?        S      0:00 [watchdog/0]             (系統監控應用,能夠在系統出現故障時自動重新啟動系統。不能殺)
5    ?        S      0:00 [migration/1]            (管理多核心(包括HypterThreading衍生的那個不大管用的、執行緒在各核心的遷移,不能殺)
6    ?        SN     0:00 [ksoftirqd/1]            (核心排程/管理第1個CPU軟中斷的守護程序,不能殺)
7    ?        S      0:00 [watchdog/1]             (系統監控應用,能夠在系統出現故障時自動重新啟動系統。不能殺)
8    ?        S<     0:00 [events/0]               (處理核心事件守護程序,不能殺)
9    ?        S<     0:00 [events/1]               (處理核心事件守護程序,不能殺)
10   ?        S<     0:00 [khelper]                (沒查出來,感覺不能殺)

11   ?        S<     0:00 [kthread]                (父核心執行緒,不能殺)   
15   ?        S<     0:00  \_ [kblockd/0]          (管理磁碟塊讀寫,不能殺)
16   ?        S<     0:00  \_ [kblockd/1]          (管理磁碟塊讀寫,不能殺)
17   ?        S<     0:00  \_ [kacpid]             (核心電源管理,不能殺)
120  ?        S<     0:00  \_ [cqueue/0]           (佇列資料結構,不能殺)
121  ?        S<     0:00  \_ [cqueue/1]           (佇列資料結構,不能殺)
124  ?        S<     0:00  \_ [khubd]              (核心的usb hub,不能殺)
126  ?        S<     0:00  \_ [kseriod]             核心執行緒
193  ?        S      0:00  \_ [pdflush]            (pdflush核心執行緒池是Linux為了回寫檔案系統資料而建立的程序,不能殺)
194  ?        S      0:00  \_ [pdflush]            (pdflush核心執行緒池是Linux為了回寫檔案系統資料而建立的程序,不能殺)

195  ?        S<     0:00  \_ [kswapd0]            (記憶體回收,確保系統空閒實體記憶體的數量在一個合適的範圍,不能殺)
196  ?        S<     0:00  \_ [aio/0]              (代替使用者程序管理io,不能殺)
197  ?        S<     0:00  \_ [aio/1]              (代替使用者程序管理io,不能殺)
354  ?        S<     0:00  \_ [kpsmoused]          (核心滑鼠支援,可以殺掉)   
387  ?        S<     0:00  \_ [ata/0]              (ata硬碟驅動,不能殺)
388  ?        S<     0:00  \_ [ata/1]              (ata硬碟驅動,不能殺)
389  ?        S<     0:00  \_ [ata_aux]            (ata硬碟驅動,不能殺)
393  ?        S<     0:00  \_ [scsi_eh_0]          (scsi裝置,不建議殺)
394  ?        S<     0:00  \_ [scsi_eh_1]          (scsi裝置,不建議殺)
395  ?        S<     0:00  \_ [scsi_eh_2]          (scsi裝置,不建議殺)
396  ?        S<     0:00  \_ [scsi_eh_3]          (scsi裝置,不建議殺)

432  ?        S<     0:00  \_ [kauditd]            (核心稽核守護程序,不能殺)
1160 ?        S<     0:00  \_ [hda_codec]
1418 ?        S<     0:00  \_ [kmirrord]           (核心守護程序控制和監視映象模組,不能殺)
400  ?        S<     0:00  \_ [kjournald]
1442 ?        S<     0:00  \_ [kjournald]
1444 ?        S<     0:00  \_ [kjournald]
1446 ?        S<     0:00  \_ [kjournald]          (kjournald Ext3檔案系統的日誌管理,通常每個mount_的 Ext3分割槽會有一個 kjournald看管,各分割槽的日誌
是獨立的,不能殺)
466  ?        S<s    0:00 /sbin/udevd -d           (udevd 支援使用者態裝置操作,不能殺)
1825 ?        Ss     0:00 syslogd -m 0             (syslogd 系統日誌程序,不能殺)
1828 ?        Ss     0:00 klogd -x                 (klogd 從核心資訊緩衝區獲取列印資訊,不能殺)
1844 ?        Ss     0:00 irqbalance               (多個CPU之間均衡分配硬體中斷,可以關閉,但不建議)

1864 ?        Ss     0:00 /usr/sbin/sshd           (sshd守護程序,不能殺)
1881 ?        Ss     0:00 crond                    (執行定時任務,不能殺)
1888 tty1     Ss+    0:00 /sbin/mingetty tty1      (mingetty 等待使用者從tty登入,可以殺)
1892 tty2     Ss+    0:00 /sbin/mingetty tty2      (mingetty 等待使用者從tty登入,可以殺)
1893 tty3     Ss+    0:00 /sbin/mingetty tty3      (mingetty 等待使用者從tty登入,可以殺)

剛剛開機之後,使用ps檢視系統內的核心執行緒,主要情況如下:   

共發現有232個核心執行緒存在,它們分別是:

   (1)kthreadd:這種核心執行緒只有一個,它的作用是管理排程其它的核心執行緒。它在核心初始化的時候被建立,會迴圈執行一個叫做kthreadd的函式,該函式的作用是執行kthread_create_list全域性連結串列中維護的kthread。可以呼叫kthread_create建立一個kthread,它會被加入到kthread_create_list連結串列中,同時kthread_create會weak up kthreadd_task。kthreadd在執行kthread會呼叫老的介面——kernel_thread執行一個名叫“kthread”的核心執行緒去執行建立的kthread,被執行過的kthread會從kthread_create_list連結串列中刪除,並且kthreadd會不斷呼叫scheduler 讓出CPU。這個執行緒不能關閉。

   (2)migration:這種核心執行緒共有32個,從migration/0到migration/31,每個處理器核對應一個migration核心執行緒,主要作用是作為相應CPU核的遷移程序,用來執行程序遷移操作,核心中的函式是migration_thread()。屬於2.6核心的負載平衡系統,該程序在系統啟動時自動載入(每個 cpu 一個),並將自己設為 SCHED_FIFO 的實時程序,然後檢查 runqueue::migration_queue 中是否有請求等待處理,如果沒有,就在 TASK_INTERRUPTIBLE 中休眠,直至被喚醒後再次檢查。migration_queue僅在set_cpu_allowed() 中新增,當程序(比如通過 APM 關閉某 CPU 時)呼叫set_cpu_allowed()改變當前可用 cpu,從而使某程序不適於繼續在當前 cpu 上執行時,就會構造一個遷移請求資料結構 migration_req_t,將其植入程序所在 cpu 就緒佇列的migration_queue 中,然後喚醒該就緒佇列的遷移 daemon(記錄在runqueue::migration_thread 屬性中),將該程序遷移到合適的cpu上去在目前的實現中,目的 cpu 的選擇和負載無關,而是"any_online_cpu(req->task->cpus_allowed)",也就是按 CPU 編號順序的第一個 allowed 的CPU。所以,和 load_balance() 與排程器、負載平衡策略密切相關不同,migration_thread() 應該說僅僅是一個 CPU 繫結以及 CPU 電源管理等功能的一個介面。這個執行緒是排程系統的重要組成部分,也不能被關閉。

      (3)watchdog:這種核心執行緒共有32個,從watchdog/0到watchdog/31, 每個處理器核對應一個watchdog 核心執行緒,watchdog用於監視系統的執行,在系統出現故障時自動重新啟動系統,包括一個核心 watchdog module 和一個使用者空間的 watchdog 程式。在Linux 核心下, watchdog的基本工作原理是:當watchdog啟動後(即/dev/watchdog裝置被開啟後),如果在某一設定的時間間隔(1分鐘)內/dev/watchdog沒有被執行寫操作, 硬體watchdog電路或軟體定時器就會重新啟動系統,每次寫操作會導致重新設定定時器。/dev/watchdog是一個主裝置號為10, 從裝置號130的字元裝置節點。 Linux核心不僅為各種不同型別的watchdog硬體電路提供了驅動,還提供了一個基於定時器的純軟體watchdog驅動。如果不需要這種故障處理機制,或者有相應的替代方案,可以在menuconfig的

   Device Drivers —>

      Watchdog Timer Support

處取消watchdog功能。

   (4)events:這種核心執行緒共有32個,從events/0到events/31, 每個處理器核對應一個 events核心執行緒。用來處理核心事件很多軟硬體事件(比如斷電,檔案變更)被轉換為events,並分發給對相應事件感興趣的執行緒進行響應。用來處理核心事件的重要執行緒,不能被去掉

   (5)khelper:這種核心執行緒只有一個,主要作用是指定使用者空間的程式路徑和環境變數, 最終執行指定的user space的程式,屬於關鍵執行緒,不能關閉

   (6)kblockd:這種核心執行緒共有32個,從kblockd/0到kblockd/31, 每個處理器核對應一個 kblockd 核心執行緒。用於管理系統的塊裝置,它會週期地啟用系統內的塊裝置驅動。如果擁有塊裝置,那麼這些執行緒就不能被去掉,要是想去掉,需要在.config中直接將CONFIG_BLOCK設成n,同時在menuconfig中取消

    Device Drivers   —>

           Block devices

   (7)kseriod:這種核心執行緒只有一個,主要作用是管理Serio總線上的裝置的各種事件,Serio是一種虛擬匯流排,是Serial I/O的輸寫,表示序列的輸入輸出裝置。對應核心中的serio_thread函式,流程大致是這樣的:呼叫serio_get_event()從連結串列中取出struct serio_event元素,然後對這個元素的事件型別做不同的時候,處理完了之後,呼叫serio_remove_duplicate_events()在連結串列中刪除相同請求的event。例如:如果要註冊新的serio裝置,它產生的事件型別是SERIO_REGISTER_PORT,然後流程會轉入serio_add_port()。使用Serio匯流排的主要是標準AT鍵盤、PS/2滑鼠、串列埠滑鼠、Sun鍵盤,以及一些遊戲手柄,不過由於I2C依賴於Serio,所以不關閉I2C就無法關閉Serio,menuconfig中SerialI/O的開關位於

Device Driver  —>

      Inputdevice support

       HardwareI/O ports

           SerialI/O support

   (8)pdflush:這種核心執行緒共有兩個,執行緒名都是pdflush,主要作用是回寫記憶體中的髒頁,回收髒頁佔據的空間。由於頁快取記憶體的快取作用,寫操作實際上會被延遲。當頁快取記憶體中的資料比後臺儲存的資料更新時,那麼該資料就被稱做髒資料。在記憶體中累積起來的髒頁最終必須被寫回。在以下兩種情況發生時,髒頁被寫回:

1.當空閒記憶體低於一個特定的閾值時,核心必須將髒頁寫回磁碟,以便釋放記憶體。

2.當髒頁在記憶體中駐留時間超過一個特定的閾值時,核心必須將超時的髒頁寫回磁碟,以確保髒頁不會無限期地駐留在記憶體中。

對於第一個目標,pdflush執行緒在系統中的空閒記憶體低於一個特定的閾值時,將髒頁重新整理回磁碟。該後臺回寫例程的目的在於在可用物理 記憶體過低時,釋放髒頁以重新獲得記憶體。特定的記憶體閾值可以通過dirty_background_ratiosysctl系統呼叫設定。當空閒記憶體比閾值:dirty_ background_ratio還低時,核心便會呼叫函式wakeup_bdflush()喚醒一個pdflush執行緒,隨後pdflush執行緒進一步 呼叫函式background_writeout()開始將髒頁寫回磁碟。函式background_ writeout()需要一個長整型引數,該引數指定試圖寫回的頁面數目。函式background_writeout()會連續地寫出資料,直到滿足以下兩個條件:

1. 已經有指定的最小數目的頁被寫出到磁碟。

2. 空閒記憶體數已經回升,超過了閾值dirty_background_ratio。

上述條件確保了pdflush操作可以減輕系統中記憶體不足的壓力。回寫操作不會在達到這兩個條件前停止,除非pdflush寫回了所有的髒頁,沒有剩下的髒頁可再被寫回了。

對於第二個目標,pdflush後臺例程會被週期性喚醒(和空閒記憶體是否過低無關),將那些在記憶體中駐留時間過長的髒頁寫出,確保記憶體中不會有長期存在的髒頁。如果系統發生崩潰,由於記憶體處於混亂之中,所以那些在記憶體中還沒來得及寫回磁碟 的髒頁就會丟失,所以週期性同步頁快取記憶體和磁碟非常重要。在系統啟動時,核心初始化一個定時器,讓它週期地喚醒pdflush執行緒,隨後使其執行函式 wb_kupdate()。該函式將把所有駐留時間超過百分之dirty_expire_centisecs秒的髒頁寫回。然後定時器將再次被初始化為百 分之dirty_expire_ centisecs秒後喚醒pdflush執行緒。總而言之,pdflush執行緒週期地被喚醒並且把超過特定期限的髒頁寫回磁碟。

系統管理員可以在/proc/sys/vm中設定回寫相關的引數,也可以通過sysctl系統呼叫設定它們

        屬於核心的記憶體管理執行緒,這個執行緒也不能被關閉

(9)kswapd0:這種核心執行緒只有一個,主要作用是用來回收記憶體。在kswapd中,有2個閥值,pages_hige和pages_low。當空閒記憶體頁的數量低於pages_low的時候,kswapd程序就會掃描記憶體並且每次釋放出32個 free pages,直到freepage的數量到達pages_high。具體回收記憶體有如下原則:

      1. 如果頁未經更改就將該頁放入空閒佇列;

      2. 如果頁已經更改並且是可備份迴文件系統的,就理解將記憶體頁的內容寫回磁碟;

      3. 如果頁已經更改但是沒有任何磁碟上的備份,就將其寫入swap分割槽。

        同樣,屬於核心的記憶體管理執行緒,這個執行緒也不能被關閉  

(10)aio:這種核心執行緒共有32個,從aio/0到aio/31, 每個處理器核對應一個 aio 核心執行緒, 代替使用者程序管理I/O,用以支援使用者態的AIO(非同步I/O),不應該被關閉。

 (11)unionfs_siod: 這種核心執行緒共有32個,但是名稱都是 unionfs_siod/,每個處理器核對應一個 unionfs_siod 核心執行緒

   (12)nfsiod:這種核心執行緒只有一個,主要作用是為nfs提供高效的緩衝機制,從而改善nfs檔案系統的效能,如果不需nfs,可以取消這一執行緒,取消這一執行緒的方法為menuconfig中取消

     File systems  —>

          Network File Systems

   (13)rpciod:這種核心執行緒共有32個,從rpciod/0到rpciod/31, 每個處理器核對應一個rpciod核心執行緒,主要作用是作為遠過程呼叫服務的守護程序,用於從客戶端啟動I/O服務,通常啟動NFS服務時要用到它,想要關閉它,需要在.config中把CONFIG_SUNRPC, CONFIG_SUNRPC_GSS, CONFIG_SUNRPC_XPRT_RDMA的值設成n

   (14)kpsmoused:這種核心執行緒只有一個,主要作用是支援ps/2介面的滑鼠驅動。如要沒有滑鼠,可以取消,取消方法是menuconfig中取消

DeviceDrivers   —>

      Input device support

       Mice