linux 進程(一)---基本概念
睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接
進程是操作系統的概念,每當我們執行一個程序時,對于操作系統來講就創建了一個進程,在這個過程中,伴隨著資源的分配和釋放。可以認為進程是一個程序的一次執行過程。 二、進程與程序的區別 程序時靜態的,它是一些保存 在磁盤上得指令的有序集合,沒有任何執行的概念。 進程是一個動態的概念,它是程序執行的過程,包括創建、調度和消亡。 三、linux系統中進程的表示 在linux系統中,進程由一個叫task_struct的結構體描述,也就是說linux中的每個進程對應一個task_struct結構體。該結構體記錄了進程的一切。下面我們來看看它的核心字段。 struct task_struct { //這個是進程的運行狀態,-1代表不可運行,0代表可運行,>0代表已經停止。 volatile long state; /* flags是進程當前的狀態標志,具體如下: 0x0000 0002表示進程正在被創建 0x0000 0004表示進程正準備退出 0x0000 0040表示此進程被fork出,但是并沒有執行exec 0x0000 0400表示此進程由于其他進程發送相關信號而被殺死 */ unsigned int flags; //表示此進程的運行優先級 unsigned int rt_priority; //該結構體記錄了進程內存使用的相關情況 struct mm_struct *mm; //進程號,是進程的唯一標識 pid_t pid; //進程組號 pid_t tgid; //real_parent是該進程的"親生父親",不管其是否被"寄養" struct task_struct *real_parent; //parent是該進程現在的父進程,有可能是"繼父" struct task_struct *parent; //這里children指的是該進程孩子的鏈表,可以得到所有孩子的進程描述符 struct list_head children; //同理,sibling該進程兄弟的鏈表,也就是其父進程的所有孩子的鏈表 struct list_head sibling; //這個是主線程的進程描述符,也許你會奇怪,為什么線程用進程描敘符表示,因為linux并沒有單獨實現線程的相關結構體,只用一 個進程來代替線程,然后對其做一些特殊的處理。 struct task_struct *group_leader; //這個是該進程所有線程的鏈表 struct list_head thread_group; //這個是該進程使用cpu時間的信息,utime是在用戶態下執行的時間,stime 是在內核態下執行的時間 cputime_t utime,stime; //comm是保存該進程名字的字符數組,長度最長為15,因為TASK_COMM_LEN為16 char comm[TASK_COMM_LEN]; //打開的文件相關信息結構體 struct files_struct *files; //信號相關信息的句柄 struct signal_struct *signal; struct sigband_struct *sighand; }; task_struct結構體非常龐大,我們沒必要去了解它的所有字段,只需要對其中比較重要的字段加以關注就可以了。從上面的分析可以看出,一個進程至少有一下東東 1. 進程號(pid),就像我們的身份證ID一樣,每個人的都不一樣。進程ID也是,是其唯一標示。 2.進程的狀態,標識進程是處于運行態,等待態,停止態,還是死亡態 A.運行態:此時進程 或者正在運行,或者準備運行 B.等待態:此時進程在等待一個事件發生或某種系統資源 C.停止態:此時進程被終止 D.死亡態:這是一個已終止的進程,但還在進程向量數組中,占有一個task_struct結構。 3.進程的優先級和時間片。不同有優先的進程,被調度運行的次序不一樣,一般是高優先級的進程先運行。時間片標識一個進程將被處理器運行的時間 4.虛擬內存 大多數進程有一些虛擬內存(內核線程和守護進程沒有) ,并且Linux必須跟蹤內存如何映射到系統物理內存。 5.處理器相關上下文 一個進程可以被認為是系統當前狀態的總和。每當一個進程運行時,它要使用處理器的寄存器、棧等,這是進程的上下文(context)。并且,每當一個進程被暫停時,所有的CPU相關上下文必須保存在該進程的task_struct中。當進程被調度器重新啟動時其上下文將從這里恢復。 四、linux進程中的文件 linux操作系統中每個進程有兩個數據結構描敘文件相關信息。

第一個:fs_struct,它包含此進程當前工作目錄和根目錄、umask。umask是新文件被 創建的缺省模式,它可以通過系統調用來改變。 第二個:files_struct,包含此進程正在使用的所有文件的信息。f_mode字段描述該文件是以什么模式創建的:只讀、讀寫、還是只寫。f_pos保存文件中下一個讀或寫將發生的位置。f_inode描敘文件的VFS索引節點,而f_ops是一個例程向量的指針,每個代表一個想施加于文件的操作的函數。 每次一個文件被打開時,files_struct中的空閑file指針之一就被用來指向新的file結構。Linux進程在啟動時有三個文件描敘符被打開了,他們是標準輸入設備、標準輸出設備和標準錯誤設備,并且通常是從創建此進程的父進程繼承得來的。所有對文件的訪問時通過傳遞或返回文件描敘符的標準系統調用進行的。這些描述符是進程fd向量的索引,所以標準輸入設備、標準輸出設備和標準錯誤設備分別對應文件描述符0、1和2。 五、進程中的虛擬內存 在Linux操作系統中,當我們運行一個二級制可執行文件時,操作系統將創建一個進程。此時如果將這個可執行二進制文件的全部代碼和數據裝入物理內存將是浪費的。因為他們不可能同時使用。隨著系統中進程數的增多,這種浪費將被成倍的擴大,系統將非常低效地運行。事實上,linux使用一種稱為請求調頁(demand-paging)的技術:只有當進程要使用時其虛擬內存時,其對應的數據才裝入物理內存。所以,不是直接把代碼和數據裝入物理內存。linux內核只修改進程的頁表,標識虛擬內存頁存在但其對應的數據不在內存中。當進程想要訪問代碼或數據時,系統硬件將產生頁故障并把控制交給Linux內核來解決。因此,對于進程地址空間中的每一個內存區,Linux都需要知道該虛擬內存來自何處,以及如何把它裝入內存以解決故障。 當一個進程分配虛擬內存時,Linux并不真正為它保留物理內存。它只是創建一個新vm_area_struct數據結構來描敘虛擬內存,這個結構被鏈入進程的虛擬內存列表。當進程試圖寫一個位于新分配虛擬內存區域的虛擬地址時,系統將產生頁故障。處理器試圖轉換該虛擬地址,但是因為沒有此內存的頁表項,它將放棄并產生一個頁故障異常,留給Linux內核來解決。Linux查看被引用的虛擬地址是否是位于當前進程的虛擬內存地址空間。如果是Linux創建適當的PTE并為此進程分配一頁物理內存。代碼或數據可能需要從文件系統或交換硬盤上讀入物理內存。然后進程可以從引起頁故障的那條指令處重啟,并且因為這次內存物理地址存在,所以它可以繼續執行。如果不是,就是大家常常見到的"段錯誤"。 呵呵,更纖細的介紹請看linux 進程地址空間的一步步探究。 from:http://blog.chinaunix.net/uid-26833883-id-3193588.htmlRFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
一、進程的定義
進程是操作系統的概念,每當我們執行一個程序時,對于操作系統來講就創建了一個進程,在這個過程中,伴隨著資源的分配和釋放。可以認為進程是一個程序的一次執行過程。 二、進程與程序的區別 程序時靜態的,它是一些保存 在磁盤上得指令的有序集合,沒有任何執行的概念。 進程是一個動態的概念,它是程序執行的過程,包括創建、調度和消亡。 三、linux系統中進程的表示 在linux系統中,進程由一個叫task_struct的結構體描述,也就是說linux中的每個進程對應一個task_struct結構體。該結構體記錄了進程的一切。下面我們來看看它的核心字段。 struct task_struct { //這個是進程的運行狀態,-1代表不可運行,0代表可運行,>0代表已經停止。 volatile long state; /* flags是進程當前的狀態標志,具體如下: 0x0000 0002表示進程正在被創建 0x0000 0004表示進程正準備退出 0x0000 0040表示此進程被fork出,但是并沒有執行exec 0x0000 0400表示此進程由于其他進程發送相關信號而被殺死 */ unsigned int flags; //表示此進程的運行優先級 unsigned int rt_priority; //該結構體記錄了進程內存使用的相關情況 struct mm_struct *mm; //進程號,是進程的唯一標識 pid_t pid; //進程組號 pid_t tgid; //real_parent是該進程的"親生父親",不管其是否被"寄養" struct task_struct *real_parent; //parent是該進程現在的父進程,有可能是"繼父" struct task_struct *parent; //這里children指的是該進程孩子的鏈表,可以得到所有孩子的進程描述符 struct list_head children; //同理,sibling該進程兄弟的鏈表,也就是其父進程的所有孩子的鏈表 struct list_head sibling; //這個是主線程的進程描述符,也許你會奇怪,為什么線程用進程描敘符表示,因為linux并沒有單獨實現線程的相關結構體,只用一 個進程來代替線程,然后對其做一些特殊的處理。 struct task_struct *group_leader; //這個是該進程所有線程的鏈表 struct list_head thread_group; //這個是該進程使用cpu時間的信息,utime是在用戶態下執行的時間,stime 是在內核態下執行的時間 cputime_t utime,stime; //comm是保存該進程名字的字符數組,長度最長為15,因為TASK_COMM_LEN為16 char comm[TASK_COMM_LEN]; //打開的文件相關信息結構體 struct files_struct *files; //信號相關信息的句柄 struct signal_struct *signal; struct sigband_struct *sighand; }; task_struct結構體非常龐大,我們沒必要去了解它的所有字段,只需要對其中比較重要的字段加以關注就可以了。從上面的分析可以看出,一個進程至少有一下東東 1. 進程號(pid),就像我們的身份證ID一樣,每個人的都不一樣。進程ID也是,是其唯一標示。 2.進程的狀態,標識進程是處于運行態,等待態,停止態,還是死亡態 A.運行態:此時進程 或者正在運行,或者準備運行 B.等待態:此時進程在等待一個事件發生或某種系統資源 C.停止態:此時進程被終止 D.死亡態:這是一個已終止的進程,但還在進程向量數組中,占有一個task_struct結構。 3.進程的優先級和時間片。不同有優先的進程,被調度運行的次序不一樣,一般是高優先級的進程先運行。時間片標識一個進程將被處理器運行的時間 4.虛擬內存 大多數進程有一些虛擬內存(內核線程和守護進程沒有) ,并且Linux必須跟蹤內存如何映射到系統物理內存。 5.處理器相關上下文 一個進程可以被認為是系統當前狀態的總和。每當一個進程運行時,它要使用處理器的寄存器、棧等,這是進程的上下文(context)。并且,每當一個進程被暫停時,所有的CPU相關上下文必須保存在該進程的task_struct中。當進程被調度器重新啟動時其上下文將從這里恢復。 四、linux進程中的文件 linux操作系統中每個進程有兩個數據結構描敘文件相關信息。

第一個:fs_struct,它包含此進程當前工作目錄和根目錄、umask。umask是新文件被 創建的缺省模式,它可以通過系統調用來改變。 第二個:files_struct,包含此進程正在使用的所有文件的信息。f_mode字段描述該文件是以什么模式創建的:只讀、讀寫、還是只寫。f_pos保存文件中下一個讀或寫將發生的位置。f_inode描敘文件的VFS索引節點,而f_ops是一個例程向量的指針,每個代表一個想施加于文件的操作的函數。 每次一個文件被打開時,files_struct中的空閑file指針之一就被用來指向新的file結構。Linux進程在啟動時有三個文件描敘符被打開了,他們是標準輸入設備、標準輸出設備和標準錯誤設備,并且通常是從創建此進程的父進程繼承得來的。所有對文件的訪問時通過傳遞或返回文件描敘符的標準系統調用進行的。這些描述符是進程fd向量的索引,所以標準輸入設備、標準輸出設備和標準錯誤設備分別對應文件描述符0、1和2。 五、進程中的虛擬內存 在Linux操作系統中,當我們運行一個二級制可執行文件時,操作系統將創建一個進程。此時如果將這個可執行二進制文件的全部代碼和數據裝入物理內存將是浪費的。因為他們不可能同時使用。隨著系統中進程數的增多,這種浪費將被成倍的擴大,系統將非常低效地運行。事實上,linux使用一種稱為請求調頁(demand-paging)的技術:只有當進程要使用時其虛擬內存時,其對應的數據才裝入物理內存。所以,不是直接把代碼和數據裝入物理內存。linux內核只修改進程的頁表,標識虛擬內存頁存在但其對應的數據不在內存中。當進程想要訪問代碼或數據時,系統硬件將產生頁故障并把控制交給Linux內核來解決。因此,對于進程地址空間中的每一個內存區,Linux都需要知道該虛擬內存來自何處,以及如何把它裝入內存以解決故障。 當一個進程分配虛擬內存時,Linux并不真正為它保留物理內存。它只是創建一個新vm_area_struct數據結構來描敘虛擬內存,這個結構被鏈入進程的虛擬內存列表。當進程試圖寫一個位于新分配虛擬內存區域的虛擬地址時,系統將產生頁故障。處理器試圖轉換該虛擬地址,但是因為沒有此內存的頁表項,它將放棄并產生一個頁故障異常,留給Linux內核來解決。Linux查看被引用的虛擬地址是否是位于當前進程的虛擬內存地址空間。如果是Linux創建適當的PTE并為此進程分配一頁物理內存。代碼或數據可能需要從文件系統或交換硬盤上讀入物理內存。然后進程可以從引起頁故障的那條指令處重啟,并且因為這次內存物理地址存在,所以它可以繼續執行。如果不是,就是大家常常見到的"段錯誤"。 呵呵,更纖細的介紹請看linux 進程地址空間的一步步探究。 from:http://blog.chinaunix.net/uid-26833883-id-3193588.htmlRFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成