程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> Processes (進程)

Processes (進程)

編輯:C語言基礎知識

  本章描述進程是什麼以及Linux如何創建、治理和刪除系統中的進程。
  
    
  
   進程執行操作系統中的任務。程序是存放在磁盤上的包括一系列機器代碼指令和數據的可執行的映像,因此,是一個被動的實體。進程可以看作是一個執行中的計算機程序。它是動態的實體,在處理器執行機器代碼指令時不斷改變。處理程序的指令和數據,進程也包括程序計數器和其他CPU的寄存器以及包括臨時數據(例如例程參數、返回地址和保存的變量)的堆棧。當前執行的程序,或者說進程,包括微處理器中所有的當前的活動。Linux是一個多進程的操作系統。進程是分離的任務,擁有各自的權利和責任。假如一個進程崩潰,它不應該讓系統中的另一個進程崩潰。每一個獨立的進程運行在自己的虛擬地址空間,除了通過安全的核心治理的機制之外無法影響其他的進程。
  
    
  
   在一個進程的生命周期中它會使用許多系統資源。它會用系統的CPU執行它的指令,用系統的物理內存來存儲它和它的數據。它會打開和使用文件系統中的文件,會直接或者間接使用系統的物理設備。Linux必須跟蹤進程本身和它使用的系統資源以便治理公平地治理該進程和系統中的其他進程。假如一個進程獨占了系統的大部分物理內存和CPU,對於其他進程就是不公平的。
  
    
  
   系統中最寶貴的資源就是CPU。通常系統只有一個。Linux是一個多進程的操作系統。它的目標是讓進程一直在系統的每一個CPU上運行,充分利用CPU。假如進程數多於CPU(多數是這樣),其余的進程必須等到CPU被釋放才能運行。多進程是一個簡單的思想:一個進程一直運行,直到它必須等待,通常是等待一些系統資源,等擁有了資源,它才可以繼續運行。在一個單進程的系統,比如DOS,CPU被簡單地設為空閒,這樣等待的時間就會被浪費。在一個多進程的系統中,同一時刻許多進程在內存中。當一個進程必須等待時操作系統將CPU從這個進程拿走,並將它交給另一個更需要的進程。是調度程序選擇了
  
   下一次最合適的進程。Linux使用了一系列的調度方案來保證公平。
  
    
  
   Linux支持許多不同的可執行文件格式,ELF是其中之一,Java是另一個。Linux必須透明地治理這些文件,因為進程使用系統的共享的庫。
  
    
  
   4.1 Linux Processes(Linux的進程)
  
    
  
   Linux中,每一個進程用一個task_strUCt(在Linux中task和process互用)的數據結構來表示,用來治理系統中的進程。Task向量表是指向系統中每一個task_struct數據結構的指針的數組。這意味著系統中最大進程數受task向量表的限制,缺省是512。當新的進程創建的時候,從系統內存中分配一個新的task_struct,並增加到task向量表中。為了更輕易查找,用current指針指向當前運行的進程。
  
   參見include/linux/sched.h
  
    
  
   除了普通進程,Linux也支持實時進程。這些進程必須對於外界事件迅速反應(因此叫做“實時”),調度程序必須和普通用戶進程區分對待。雖然task_struct數據結構十分巨大、復雜,但是它的域可以分為以下的功能:
  
    
  
   State 進程執行時它根據情況改變狀態(state)。Linux進程使用以下狀態:(這裡漏掉了SWAPPING,因為看來沒用到)
  
   Running 進程在運行(是系統的當前進程)或者預備運行(等待被安排到系統的一個CPU上)
  
   Waiting 進程在等待一個事件或資源。Linux區分兩種類型的等待進程:可中斷和不可中斷的(interruptible and uninterruptible)。可中斷的等待進程可以被信號中斷,而不可中斷的等待進程直接等待硬件條件,不能被任何情況中斷。
  
   Stopped 進程停止了,通常是接收到了一個信號。正在調試的進程可以在停止狀態。
  
   Zombie 終止的進程,因為某種原因,在task 向量表重任舊有一個task_struct數據結構的條目。就想聽起來一樣,是一個死亡的進程。
  
    
  
   Scheduling Information 調度者需要這個信息用於公平地決定系統中的進程哪一個更應該運行。
  
   Identifiers 系統中的每一個進程都有一個進程標識符。進程標識符不是task向量表中的索引,而只是一個數字。每一個進程也都有用戶和組(user and group)的標識符。用來控制進程對於系統中文件和設備的訪問。
  
  
   Inter-Process Communication Linux支持傳統的UNIX-IPC機制,即信號,管道和信號燈(semaphores),也支持系統V的IPC機制,即共享內存、信號燈和消息隊列。關於Linux支持的IPC機制在第5章中描述。
  
   Links 在Linux系統中,沒有一個進程是和其他進程完全無關的。系統中的每一個進程,除了初始的進程之外,都有一個父進程。新進程不是創建的,而是拷貝,或者說從前一個進程克隆的(cloned)。每一個進程的task_struct中都有指向它的父進程和兄弟進程(擁有相同的父進程的進程)以及它的子進程的的指針。在Linux系統中你可以用pstree命令看到正在運行的進程的家庭關系。
  
    
  
   init(1)-+-crond(98)
  
   -emacs(387)
  
   -gpm(146)
  
   -inetd(110)
  
   -kerneld(18)
  
   -kflushd(2)
  
   -klogd(87)
  
   -kswapd(3)
  
   -login(160)---bash(192)---emacs(225)
  
   -lpd(121)
  
   -mingetty(161)
  
   -mingetty(162)
  
   -mingetty(163)
  
   -mingetty(164)
  
   -login(403)---bash(404)---pstree(594)
  
   -sendmail(134)
  
   -syslogd(78)
  
   `-update(166)
  
    
  
   另外系統中的所有的進程信息還存放在一個task_struct數據結構的雙向鏈表中,根是init進程。這個表讓Linux可以查到系統中的所有的進程。它需要這個表以提供對於ps或者kill等命令的支持。
  
   Times and Timers 在一個進程的生命周期中,核心除了跟蹤它使用的CPU時間還記錄它的其他時間。每一個時間片(clock tick),核心更新jiffies中當前進程在系統和用戶態所花的時間綜合。Linux也支持進程指定的時間間隔的計數器。進程可以使用系統調用建立計時器,在計時器到期的時候發送信號給自己。這種計時器可以是一次性的,也可是周期性的。
  
   File system 進程可以根據需要打開或者關閉文件,進程的task_struct結構存放了每一個打開的文件描述符的指針和指向兩個VFS I節點(inode)的指針。每一個VFS I節點唯一描述一個文件系統中的一個文件或目錄,也提供了對於底層文件系統的通用接口。Linux下如何支持文件系統在第9章中描述。第一個I節點是該進程的根(它的主目錄),第二個是它的當前或者說pwd目錄。Pwd取自Unix命令:印出工作目錄。這兩個VFS節點本身有計數字段,隨著一個或多個進程引用它們而增長。這就是為什麼你不能刪除一個進程設為工作目錄的目錄。
  
   Virtual memory 多數進程都有一些虛擬內存(核心線程和核心守護進程沒有),Linux核心必須知道這些虛擬內存是如何映射到系統的物理內存中的。
  
   Processor Specific Context 進程可以看作是系統當前狀態的總和。只要進程運行,它就要使用處理器的寄存器、堆棧等等。當一個進程暫停的時候,這些進程的上下文、和CPU相關的上下文必須保存到進程的task_struct結構中。當調度者重新啟動這個進程的時候,它的上下文就從這裡恢復。
  
    
  
   4.2 Identifiers (標識)
  
    
  
   Linux,象所有的Unix,使用用戶和組標識符來檢查對於系統中的文件和映像的訪問權限。Linux系統中所有的文件都有所有權和許可,這些許可描述了系統對於該文件或目錄擁有什麼樣的權限。基本的權限是讀、寫和執行,並分配了3組用戶:文件屬主、屬於特定組的進程和系統中的其他進程。每一組用戶都可以擁有不同的權限,例如一個文件可以讓它的屬主讀寫,它的組讀,而系統中的其他進程不能訪問。
  
    
  
   Linux使用組來給一組用戶賦予對文件或者目錄的權限,而不是對系統中的單個用戶或者進程賦予權限。比如你可以為一個軟件項目中的所有用戶創建一個組,使得只有他們才能夠讀寫項目的源代碼。一個進程可以屬於幾個組(缺省是32個),這些組放在每一個進程的task_struct結構中的groups向量表中。只要進程所屬的其中一個組對於一個文件有訪問權限,則這個進程就又對於這個文件的適當的組權限。
  
   一個進程的task_struct中有4對進程和組標識符。
  
   Uid,gid 該進程運行中所使用的用戶的標識符和組的標識符
  
   Effective uid and gid 一些程序把執行進程的uid和gid 改變為它們自己的(在VFS I節點執行映像的屬性中)。這些程序叫做setuid程序。這種方式有用,因為它可以限制對於服務的訪問,非凡是那些用其他人的方式運行的,例如網絡守護進程。有效的uid 和gid來自setuid程序,而uid和gid 仍然是原來的。核心檢查特權的時候檢查有效 uid和gid。
  
   File system uid and gid 通常和有效uid和gid相等,檢查對於文件系統的訪問權限。用於通過NFS安裝的文件系統。這時用戶態的NFS服務器需要象一個非凡進程一樣訪問文件。只有文件系統uid和gid改變(而非有效uid和gid)。這避免了惡意用戶向NFS的服務程序發送Kill信號。Kill用一個非凡的有效uid和gid發送給進程
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved