程序是unix作業系統的最重要的抽象之一,它是處於執行期的程式,但是它不僅僅包括**,還包括相關的檔案,掛起訊號等資源。執行緒是程序活動的物件,每個執行緒都有乙個程式計數器,程序棧和一組程序計數器。linux中線程是程序的一種特例。
程序提供兩種虛擬機制,虛擬處理器和虛擬記憶體。
linux系統中通過fork()系統呼叫來產生新的程序,產生的方式是複製當期的程序來產生新程序,所以呼叫fork()的程序稱為父程序,新產生的程序被稱為子程序。linux系統中fork()是呼叫clone()這個系統呼叫。
1、程序描述符及任務結構
核心程序放在乙個角task_list的雙向迴圈煉表裡,每乙個節點都是乙個task_struct,稱為程序描述符,該結構定義在中。task_struct包含了描述乙個程序的完整資訊。
1.1分配程序描述符
linux通過slab分配器來分配task_struct結構,這樣能達到物件復用和快取著色,(通過預分配和重複使用task_struct,可以避免動態分配和釋放所帶來的資源消耗,從而使得程序建立的速度較快)。現在不需要專門的暫存器,只需要在棧底放乙個thread_info,這個struct可以方便快速計算出task_struct所在位置。
1.2程序描述符的存放
linux為每個程序分配了乙個pid,實際是個int型別,其預設最大值為32768,核心把每個程序的pid放在程序描述符中。這個值越小,轉一圈的時間就越快。如果需要,可以修改/proc/sys/kernel/pid_max裡的內容來修改最大值。
1.3程序的狀態
1.4設定狀態
記憶體需要經常設定程序的狀態,這時候可以呼叫set_task_state(tast,state)函式來設定。
1.5程序上下文
在使用者態執行的程序在系統呼叫和傳送異常時會進入核心態,這時核心就成為代表程式執行的的程序上下文。
1.6程序家族樹
linux程序具備繼承關係,所有的繼承都是pid為1的init程序的後代。核心在系統啟動的最後節點啟動init程序,該程序讀取初始化指令碼,並執行其他的相關程式,最終完成系統啟動的整個過程。每個task_struct都包含乙個parent節點的指標和乙個children的鍊錶。
2程序建立
許多其他的作業系統都提供了產生整合的機制,首先在位址空間裡建立程序,讀入可執行檔案,最後開始執行。unix採用了與眾不同的實現方式,它把上述步驟分解到兩個單獨的函式中去執行:fork()和exec()函式族。首先,fork()通過拷貝當期程序建立乙個子程序。子程序與父程序的區別僅僅在於pid、ppd和默寫資源和統計裡。exec()函式負責拂去可執行檔案並將其載入位址空間開始執行。
2.1寫時拷貝
linux的fork()使用寫時拷貝頁實現。寫時拷貝可以推遲甚至免除拷貝資料。核心此時不複製整個程序的位址空間,二是讓父程序和子程序共享乙個拷貝。還有在需要寫入的時候,資料才會被複製,從而使各個程序擁有各自的拷貝。而一般情況下,fork()之後立即呼叫exec(),它們就無需複製了,fork()的實際開銷就是複製父程序的頁表及自己吃建立唯一的基礎描述符。在一般情況下,程序建立後都會馬上執行乙個可執行檔案,這種優化可以避免拷貝大量根本就不會被使用的資料。
2..2 fork()
fork()通過clone()系統呼叫實現,clone()呼叫do_fork(),do_fork完成大部分工作,它定義在kernel/fork.c檔案中。該函式呼叫copy_process()函式,然後讓進城開始執行。copy_process()函式完成的工作:
1、呼叫dup_task_struct()為新程序建立乙個核心棧,threa_info結構和task_struct,這些值與當期程序值形同。連程序描述符也是完全相同。
2、檢測新建立的這個子程序後,當期使用者所擁有的程序數目有沒有超過最大值。
3、現在,程序著手是自己與父程序區別開。程序描述符內的許多成員都要被請0或設定為初始值。程序描述符的成員值不是繼承而來的,而主要是統計資訊。程序描述符中大多數資料都是共享的。
4、接下來,子程序的狀態被設定為task_uninterrupteble以保證她不會投入執行。
5、copy_process()呼叫copy_flags()以更新task_struct的flags成員。表面程序是否擁有超級使用者許可權的pf_superriv標誌被請0.表明程序還沒有呼叫exec()函式的pf_forknoexec標誌被設定。
6、呼叫get_pid()為新進場獲取乙個有效的pid。
7、根據傳遞給clone()的引數標誌,copy_process()拷貝或共享開啟的檔案、檔案系統資訊、訊號處理函式、程序位址空間和命名空間等。在一般情況下,這些資源會被給定的程序的左右程序共享;否則,這些資源對每個程序是不同的,因此被拷貝到這裡。
8、讓父程序和子程序評分剩餘的時間片。
9、最後,copy_process()函式作搜啊為歐諾工作,並返回乙個指向子程序的指標。
最後回到do_fork()函式。
Linux學習之程序
程序process pid 子程序 ppid 父程序 top 動態檢視系統程序占用資源高,不常用 ps aus 靜態檢視當前系統程序,常用。sort cpu 以cpu使用率來排序,降序 sort cpu 以cpu使用率來排序,公升序 sort mem 以記憶體占用情況來排序,降序。vsz rss t...
Linux 程序學習 一
知識點1 程序概念 程序是作業系統最核心的概念之一。程序簡單而言是作業系統中執行的程式,它是作業系統資源管理的最小單元。程序是乙個動態的實體,是程式的一次執行過程。程序和程式的區別在於 程序是動態的,程式是靜態的,程序是執行中的程式,而程式是儲存在硬碟上的可執行的 知識點2 程序三態 1 執行 乙個...
Linux程序學習(一)
程序是乙個動態的實體,是程式執行的一次過程。程序是作業系統資源分配的基本單位。區分程序和程式,程序是動態的,程式是靜態的 程序是執行中的程式,程式是一些可執行的 linux下可通過命令ps或pstree或ps af檢視當前系統中的程序。如圖所示 再認識幾個id 在unistd.h標頭檔案中,以下是獲...