2012年2月7日 星期二

linux上x86的process management(1)

主要來自兩本書

以一般作業系統的角度,process是最基本的工作(task)單位,thread是後來更新的想法,所以基本上一般的OS還是對以process為基本出發點,再進一步以thread做管理(印象中M$號稱他們全部都是thread)
現在流行的CPU大多是以multi-tasking為出發點,也就是在概念上必須能夠同時執行多個task,可是以前one-core也好,到現在的multi-core也罷,工作項目大多遠遠超過core的個數,所以都是以快速工作切換的方式達到同時處理多個task,快到讓使用者沒有感覺
在切換task的時候,其實大多可以看成切換process,至於要挑哪個process,就交給重要的元件名為排程(scheduler)來完成,功能是挑選process放到CPU上執行,scheduler會對process的處理,會導致process處於不同的狀態,這些狀態也會反過來影響scheduler挑選的一些依據。

  • create : 嚴格來說跟scheduler無關,是指process剛剛被建立,建立完成後就會通知scheduler,加入排程的隊伍(queue)
  • wait : process可能還輪不到他執行,他在queue裡面等待
  • suspend : process在等待某些資源,例如網路的封包或者硬碟檔案的傳輸
  • running : process正在CPU上面執行
  • stop : process已經完成工作,可能在等待資源回收

所以process的一生從建立後,scheduler讓process在queue內等待,到可能執行scheduler配給的cpu時間用完,又回到queue內,或者因為在等待某些資源等等的狀態轉換,到最後執行完畢。上面是一般高階的概念思考,Linux則有些更細緻的分辨以及實作上的考量。

Linux並沒有create的狀態,Linux透過fork()以及exec()兩個system call完成建立的工作,接下來task/process的狀態會被記錄在task_struct這個資料結構內有
  • TASK_RUNNING : 正在執行
  • TASK_INTERRUPTIBLE : 可能正在等待某個event/signal發生
  • TASK_UNINTERRUPTIBLE : 在正等待kernel的某個event/signal
  • TASK_STOPPED : 程式停止中,或許是時間用完,或許是被debugger中斷
  • TASK_TRACED : 程式被trace當中
  • EXIT_ZOMBIE : zombie死亡狀態(這是unix/linux的一種特別process結束的狀態)
  • EXIT_DEAD : 正常結束
task_struct這個資料結構內容遠遠超出只有上面那些,大致上有
  • 執行狀態(就上面提到的那些)
  • memory資訊
  • 一些process的必須資料,如process id (PID), group ID ...等等
  • 使用中的檔案描述(File descriptor)
  • thread的information(一些CPU相關的資訊)
  • signal的handler
當程式(program)變成process(比方說大家同時在使用ls指令/program,你跟我在執行相同的程式碼,但是是不同的processes)的時候,一個process大致上可以被分成兩種模式user mode(ring 3)跟kernel mode(ring 0),雖然intel提供四種權限分類,但是linux只有使用兩種。兩種模式的差別在user mode程式只能存取自己user space內的東西,但是無法取得一些類似硬體的資源(比方寫入硬碟),如果要使用硬體資源,則必須透過system call或者interrupt(中斷)的方式,這時候kernel就會介入,在kernel監控下,讓使用者程式合理的權限允許下寫入,不合理行為是不被允許(例如把你的數值寫到他人的檔案內或者記憶體中)。中斷則由硬體產生或者程式自己安排的,例如印表機可用的時候告訴process,他想印東西,或者系統通知該process可能某些硬體出了一些狀況。
因為system call或者interrupt的關係,可能導致程式執行到一半被通知要處理其他事情,這時候大致上有三種處理方式
  1. 必須馬上處理的interrupt,要火速處理,該process被block,不管他是在user mode或者kernel mode
  2. 該process也在kernel處理要緊事,先把這件事情擱著,待會處理
  3. 雖然process在kernel的事情很要緊,但是process的事情的優先權低於該interrupt,先處理該interrupt
  4. 最後其實還有一個稱為kernel preemption的內容

作業系統在管理process的時候,以傳統的方式是記錄在一張表上,linux上面有一堆process,每個process都有自己一個獨一無二的ID編號(一個整數值),用以當作process的辨識號碼,但是隨著virtualization的盛行,已經不再只有pid,還有更複雜的namespace機制,以後再談。

當成是被建立之後,他必須配置一堆相關資源(包含PID),跟著在被sheduler藉由PID以及其他資訊加以排程進入CPU處理。

中間有個重要的過程就是建立的部分,包含了記憶體的配置...等等,主要牽涉到fork()、clone()、exec()等三個重要的system call

沒有留言:

張貼留言