進程概念介紹

   進程是操作系統(tǒng)對運行程序的一種抽象。

? 一個正在執(zhí)行的程序;

? 一個正在計算機上執(zhí)行的程序?qū)嵗?/span>

? 能分配給處理器并由處理器執(zhí)行的實體;

? 一個具有普以下特征的活動單元:一組指令序列的執(zhí)行、一個當前狀態(tài)和相關(guān)的系統(tǒng)資源集。

內(nèi)核觀點:擔當分配系統(tǒng)資源(CPU時間,內(nèi)存)的實體。進程的兩個基本元素:程序代碼(可能被執(zhí)行的其他進程共享)、數(shù)據(jù)集。進程是一種動態(tài)描述,但是并不代表所有的進程都在運行。(進程在內(nèi)存中因策略或調(diào)度需求,會處于各種狀態(tài)) 進程是處于執(zhí)行期的程序以及它所管理的資源(如打開的文件、掛起的信號、進程狀態(tài)、地址空間等等)的總稱。注意,程序并不是進程,實際上兩個或多個進程不僅有可能執(zhí)行同一程序,而且還有可能共享地址空間等資源。
進程描述

   ?義上,所有的進程信息被放在?個叫做進程控制塊的數(shù)據(jù)結(jié)構(gòu)中,可以理解為進程屬性的集合,該控制塊由操作系統(tǒng)創(chuàng)建和管理。
進程控制塊

   進程控制塊是操作系統(tǒng)能夠支持多線程和提供多重處理技術(shù)的關(guān)鍵工具。每個進程在內(nèi)核中都有?個進程控制塊(PCB)來維護進程相關(guān)的信息,Linux內(nèi)核的 進程控制塊是task_struct結(jié)構(gòu)體?,F(xiàn)在我們?nèi)?了解?下其中都有哪些信息。 在Linux中,這個結(jié)構(gòu)叫做task_struct。task_struct是Linux內(nèi)核的?種數(shù)據(jù)結(jié)構(gòu),它會被裝載到RAM?并且包含著進程的信息。每個進程都把它的信息放在 task_struct 這個數(shù)據(jù)結(jié)構(gòu)?,并且可以在 include/linux/sched.h ?找到它。所有運?在系統(tǒng)?的進程都以 task_struct 鏈表的形式存在內(nèi)核?。task_struct 包含了這些內(nèi)容
1、進程標?符(PID):描述本進程的唯?標?符,?來區(qū)別其他進程。?進程id(PPID)

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

1  pid_t pid;   //這個是進程號2  pid_t tgid;  //這個是進程組號3  pid_t Uid;   //用戶標識符4  pid_t Euid; //有效用戶標識符5  pid_t egid; //有效組標識符6  pid_t Suid; //備份用戶標識符7  pid_t sgid; //備份組標識符8  pid_t Fsuid; //文件系統(tǒng)用戶標識符9  pid_t fsgid;  //文件系統(tǒng)組標識符

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

在CONFIG_BASE_SMALL配置為0的情況下,PID的取值范圍是0到32767,即系統(tǒng)中的進程數(shù)最大為32768個。

1 /* linux-2.6.38.8/include/linux/threads.h */  2 #define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 :0x8000)

   在Linux系統(tǒng)中,一個線程組中的所有線程使用和該線程組的領(lǐng)頭線程(該組中的第一個輕量級進程)相同的PID,并被存放在tgid成員中。只有線程組的領(lǐng)頭線程的pid成員才會被設置為與tgid相同的值。注意,getpid()系統(tǒng)調(diào)用返回的是當前進程的tgid值而不是pid值。

2、進程狀態(tài) : 任務狀態(tài),退出代碼,退出信號等。

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 1   volatile long state;  
 2    int exit_state;   4   /*state成員的可能取值如下:*/ 5   #define TASK_RUNNING        0   //TASK_RUNNING表示進程要么正在執(zhí)行,要么正要準備執(zhí)行。 6   #define TASK_INTERRUPTIBLE  1   //TASK_INTERRUPTIBLE表示進程被阻塞(睡眠),直到某個條件變?yōu)檎?。條件一旦達成,進程的狀態(tài)就被設置為TASK_RUNNING。 7   #define TASK_UNINTERRUPTIBLE   2 //TASK_UNINTERRUPTIBLE的意義與TASK_INTERRUPTIBLE類似,除了不能通過接受一個信號來喚醒以外。 8   #define __TASK_STOPPED      4   // __TASK_STOPPED表示進程被停止執(zhí)行。 9   #define __TASK_TRACED       8  //__TASK_TRACED表示進程被debugger等進程監(jiān)視。10   /* in tsk->exit_state */  11  #define EXIT_ZOMBIE     16  //EXIT_ZOMBIE表示進程的執(zhí)行被終止,但是其父進程還沒有使用wait()等系統(tǒng)調(diào)用來獲知它的終止信息。12  #define EXIT_DEAD       32   EXIT_DEAD表示進程的最終狀態(tài)。13  /* in tsk->state again */  14  #define TASK_DEAD       64  
15  #define TASK_WAKEKILL       128  
16  #define TASK_WAKING     256 
17 /*EXIT_ZOMBIE和EXIT_DEAD也可以存放在exit_state成員中。*/

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

    volatile這個關(guān)鍵詞是告訴編譯器不要對其優(yōu)化,編譯器有一個緩存優(yōu)化的習慣,比如說,第一次在內(nèi)存取數(shù),編譯器發(fā)現(xiàn)后面還要用這個變量,于是把這個變量的值就放在寄存器中。這個關(guān)鍵詞就是要求編譯器不要優(yōu)化,每次都讓CPU去內(nèi)存取數(shù)。以確保狀態(tài)的變化能及時地反映上來。

3、進程調(diào)度(優(yōu)先級 : 相對于其他進程的優(yōu)先級。)

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

     unsigned  rt_priority;    sched_class *sched_class;      unsigned  policy;   cpumask_t cpus_allowed;   SCHED_NORMAL        0    SCHED_FIFO      1    SCHED_RR        2     SCHED_BATCH     3       SCHED_IDLE      5                            sched_class stop_sched_class;

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 實時優(yōu)先級范圍是0到MAX_RT_PRIO-1(即99),而普通進程的靜態(tài)優(yōu)先級范圍是從MAX_RT_PRIO到MAX_PRIO-1(即100到139)。值越大靜態(tài)優(yōu)先級越低。

4、表示進程親屬關(guān)系的成員

 在Linux系統(tǒng)中,所有進程之間都有著直接或間接地聯(lián)系,每個進程都有其父進程,也可能有零個或多個子進程。擁有同一父進程的所有進程具有兄弟關(guān)系。

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

1 struct task_struct *real_parent; /* real parent process ,real_parent指向其父進程,如果創(chuàng)建它的父進程不再存在,則指向PID為1的init進程。 */  2 struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports, parent指向其父進程,當它終止時,必須向它的父進程發(fā)送信號。它的值通常與real_parent相同。 */  3 struct list_head children;  /* list of my children, children表示鏈表的頭部,鏈表中的所有元素都是它的子進程。 */  4 struct list_head sibling;   /* linkage in my parent's children list, sibling用于把當前進程插入到兄弟鏈表中。 */  5 struct task_struct *group_leader;   /* threadgroup leader ,group_leader指向其所在進程組的領(lǐng)頭進程。*/

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

   可以用下面這些通俗的關(guān)系來理解它們:real_parent是該進程的”親生父親“,不管其是否被“寄養(yǎng)”;parent是該進程現(xiàn)在的父進程,有可能是”繼父“;這里children指的是該進程孩子的鏈表,可以得到所有孩子的進程描述符,但是需使用list_for_each和list_entry,list_entry其實直接使用了container_of,同理,sibling該進程兄弟的鏈表,也就是其父親的所有孩子的鏈表。用法與children相似;struct task_struct *group_leader這個是主線程的進程描述符,也許你會奇怪,為什么線程用進程描述符表示,因為linux并沒有單獨實現(xiàn)線程的相關(guān)結(jié)構(gòu)體,只是用一個進程來代替線程,然后對其做一些特殊的處理;struct list_head thread_group;這個是該進程所有線程的鏈表。

5、進程標記

   反應進程狀態(tài)的信息,但不是運行狀態(tài),用于內(nèi)核識別進程當前的狀態(tài),以備下一步操作

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 1 unsigned int flags; /* per process flags, defined below */   2 // flags成員的可能取值如下: 3 #define PF_KSOFTIRQD    0x00000001  /* I am ksoftirqd */  
 4 #define PF_STARTING 0x00000002  /* being created */  
 5 #define PF_EXITING  0x00000004  /* getting shut down */  
 6 #define PF_EXITPIDONE   0x00000008  /* pi exit done on shut down */  
 7 #define PF_VCPU     0x00000010  /* I'm a virtual CPU */  
 8 #define PF_WQ_WORKER    0x00000020  /* I'm a workqueue worker */  
 9 #define PF_FORKNOEXEC   0x00000040  /* forked but didn't exec */  
10 #define PF_MCE_PROCESS  0x00000080      /* process policy on mce errors */  
11 #define PF_SUPERPRIV    0x00000100  /* used super-user privileges */  
12 #define PF_DUMPCORE 0x00000200  /* dumped core */  
13 #define PF_SIGNALED 0x00000400  /* killed by a signal */  
14 #define PF_MEMALLOC 0x00000800  /* Allocating memory */  
15 #define PF_USED_MATH    0x00002000  /* if unset the fpu must be initialized before use */  
16 #define PF_FREEZING 0x00004000  /* freeze in progress. do not account to load */  
17 #define PF_NOFREEZE 0x00008000  /* this thread should not be frozen */  
18 #define PF_FROZEN   0x00010000  /* frozen for system suspend */  
19 #define PF_FSTRANS  0x00020000  /* inside a filesystem transaction */  
20 #define PF_KSWAPD   0x00040000  /* I am kswapd */  
21 #define PF_OOM_ORIGIN   0x00080000  /* Allocating much memory to others */  
22 #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */  
23 #define PF_KTHREAD  0x00200000  /* I am a kernel thread */  
24 #define PF_RANDOMIZE    0x00400000  /* randomize virtual address space */  
25 #define PF_SWAPWRITE    0x00800000  /* Allowed to write to swap */  
26 #define PF_SPREAD_PAGE  0x01000000  /* Spread page cache over cpuset */  
27 #define PF_SPREAD_SLAB  0x02000000  /* Spread some slab caches over cpuset */  
28 #define PF_THREAD_BOUND 0x04000000  /* Thread bound to specific cpu */  
29 #define PF_MCE_EARLY    0x08000000      /* Early kill for mce process policy */  
30 #define PF_MEMPOLICY    0x10000000  /* Non-default NUMA mempolicy */  
31 #define PF_MUTEX_TESTER 0x20000000  /* Thread belongs to the rt mutex tester */  
32 #define PF_FREEZER_SKIP 0x40000000  /* Freezer should not count it as freezable */  
33 #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

6、進程內(nèi)核棧

進程通過alloc_thread_info函數(shù)分配它的內(nèi)核棧,通過free_thread_info函數(shù)釋放所分配的內(nèi)核棧。

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 1 void *stack; 
 2 // 3 /* linux-2.6.38.8/kernel/fork.c */    4 static inline struct thread_info *alloc_thread_info(struct task_struct *tsk)  
 5 {  
 6 #ifdef CONFIG_DEBUG_STACK_USAGE  
 7     gfp_t mask = GFP_KERNEL | __GFP_ZERO;  
 8 #else   9     gfp_t mask = GFP_KERNEL;  
10 #endif  11     return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);  
12 }  
13 static inline void free_thread_info(struct thread_info *ti)  
14 {  
15     free_pages((unsigned long)ti, THREAD_SIZE_ORDER);  
16 }  
17  /*其中,THREAD_SIZE_ORDER宏在linux-2.6.38.8/arch/arm/include/asm/thread_info.h文件中被定義為1,也就是說alloc_thread_info函數(shù)通過調(diào)用__get_free_pages函數(shù)分配2個頁的內(nèi)存(它的首地址是8192字節(jié)對齊的)。18 19     Linux內(nèi)核通過thread_union聯(lián)合體來表示進程的內(nèi)核棧,其中THREAD_SIZE宏的大小為8192。 */20 union thread_union {  
21     struct thread_info thread_info;  
22     unsigned long stack[THREAD_SIZE/sizeof(long)];  
23 };  
24 /*當進程從用戶態(tài)切換到內(nèi)核態(tài)時,進程的內(nèi)核棧總是空的,所以ARM的sp寄存器指向這個棧的頂端。因此,內(nèi)核能夠輕易地通過sp寄存器獲得當前正在CPU上運行的進程。*/25 /* linux-2.6.38.8/arch/arm/include/asm/current.h */  26 static inline struct task_struct *get_current(void)  
27 {  
28     return current_thread_info()->task;  
29 }  
30   31 #define current (get_current())  
32   33 /* linux-2.6.38.8/arch/arm/include/asm/thread_info.h */   34 static inline struct thread_info *current_thread_info(void)  
35 {  
36     register unsigned long sp asm ("sp");  
37     return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));  
38 }

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

下圖中顯示了在物理內(nèi)存中存放兩種數(shù)據(jù)結(jié)構(gòu)的方式。線程描述符駐留與這個內(nèi)存區(qū)的開始,而棧頂末端向下增長。iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓在這個圖中,esp寄存器是CPU棧指針,用來存放棧頂單元的地址。在80x86系統(tǒng)中,棧起始于頂端,并朝著這個內(nèi)存區(qū)開始的方向增長。從用戶態(tài)剛切換到內(nèi)核態(tài)以后,進程的內(nèi)核??偸强盏?。因此,esp寄存器指向這個棧的頂端。一旦數(shù)據(jù)寫入堆棧,esp的值就遞減。

7、ptrace系統(tǒng)調(diào)用 

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

 1 unsigned int ptrace;  
 2 struct list_head ptraced;  
 3 struct list_head ptrace_entry;  
 4 unsigned long ptrace_message;  
 5 siginfo_t *last_siginfo; /* For ptrace use.  */   6 ifdef CONFIG_HAVE_HW_BREAKPOINT  
 7 atomic_t ptrace_bp_refcnt;  
 8 endif  
 9 /*成員ptrace被設置為0時表示不需要被跟蹤,它的可能取值如下:*/10 /* linux-2.6.38.8/include/linux/ptrace.h */  11 #define PT_PTRACED  0x00000001  
12 #define PT_DTRACE   0x00000002  /* delayed trace (used on m68k, i386) */  
13 #define PT_TRACESYSGOOD 0x00000004  
14 #define PT_PTRACE_CAP   0x00000008  /* ptracer can follow suid-exec */  
15 #define PT_TRACE_FORK   0x00000010  
16 #define PT_TRACE_VFORK  0x00000020  
17 #define PT_TRACE_CLONE  0x00000040  
18 #define PT_TRACE_EXEC   0x00000080  
19 #define PT_TRACE_VFORK_DONE 0x00000100  
20 #define PT_TRACE_EXIT   0x00000200

iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

8、Performance Event 

http://www.cnblogs.com/33debug/p/6705391.html