??????1.進程相關概念
??????進程是代碼的一次動態執行,擔當分配系統資源的角色,進程信息是被放在一個一個數據結構中,是一個結構體task_struct
??????2.進程控制塊內容
????????????????????
//linux下的進程控制塊
struct task_struct {volatile long state;// 說明了該進程是否可以執行,還是可中斷等信息unsigned long flags;// Flage 是進程號,在調用fork()時給出int sigpending;// 進程上是否有待處理的信號 mm_segment_t addr_limit;// 進程地址空間,區分內核進程與普通進程在內存存放的位置不同0 - 0xBFFFFFFF for user - thead0 - 0xFFFFFFFF for kernel - threadvolatile long need_resched; //調度標志,表示該進程是否需要重新調度, 若非 0, 則當從內核態返回到用戶態,會發生調度 int lock_depth;//鎖深度 long nice; //進程的基本時間片 unsigned long policy; //進程的調度策略,有三種 實時進程:SCHED_FIFO,SCHED_RR 分時進程:SCHED_OTHER struct mm_struct mm; //進程內存管理信息 int processor; //若進程不在任何CPU上運行。cpus_runnable 的值是0,否則是1。 這個值在運行隊列被鎖時更新. unsigned long cpus_runnable, cpus_allowed;struct list_head run_list; //指向運行隊列的指針 unsigned long sleep_time; //進程的睡眠時間 struct task_struct next_task, prev_task; //用于將系統中所有的進程連成一個雙向循環鏈表,其根是init_task. struct mm_struct active_mm;truct list_head local_pages; //指向本地頁面unsigned int allocation_order, nr_local_pages;struct linux_binfmt binfmt;// 進程所運行的可執行文件的格式int exit_code, exit_signal;int pdeath_signal;// 父進程終止是向子進程發送的信號unsigned long personality; // Linux 可以運行由其他UNIX操作系統生成的符合iBCS2標準的程序int did_exec : 1; //按POSIX要求設計的布爾量,區分進程正在執行從父進程中繼承的代碼,還是執行由execve裝入的新程序代碼 pid_t pid;// 進程標識符,用來代表一個進程pid_t pgrp; //進程組標識,表示進程所屬的進程組pid_t tty_old_pgrp; //進程控制終端所在的組標識pid_t session; //進程的會話標識pid_t tgid;int leader; //標志,表示進程是否為會話主管struct task_structp_opptr p_pptr, p_cptr, p_ysptr, p_osptr;struct list_head thread_group;// 線程鏈表struct task_struct pidhash_next; //用于將進程鏈入HASH表pidhash struct task_struct pidhash_pprev;wait_queue_head_t wait_chldexit; //供wait4()使用struct completion vfork_done; //供vfork() 使用 unsigned long rt_priority; // 實時優先級,用它計算實時進程調度時的weight值,unsigned long it_real_value, it_prof_value, it_virt_value;unsigned long it_real_incr, it_prof_incr, it_virt_value;struct timer_list real_timer;//指向實時定時器的指針struct tms times; //記錄進程消耗的時間,unsigned long start_time;//進程創建的時間long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];//記錄進程在每個CPU上所消耗的用戶態時間和核心態時間mm fault and swap info : this can arguably be seen as eithermm - specific or thread - specific//內存缺頁和交換信息://min_flt, maj_flt累計進程的次缺頁數(Copy on Write頁和匿名頁)和主缺頁數(從映射文件或交換設備讀入的頁面數);//nswap記錄進程累計換出的頁面數,即寫到交換設備上的頁面數。//cmin_flt, cmaj_flt, cnswap記錄本進程為祖先的所有子孫進程的累計次缺頁數,主缺頁數和換出頁面數。在父進程//回收終止的子進程時,父進程會將子進程的這些信息累計到自己結構的這些域中unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;int swappable : 1; //表示進程的虛擬地址空間是否允許換出process credentials ///進程認證信息//uid,gid為運行該進程的用戶的用戶標識符和組標識符,通常是進程創建者的uid,gid //euid,egid為有效uid,gid//fsuid,fsgid為文件系統uid,gid,這兩個ID號通常與有效uid,gid相等,在檢查對于文件系統的訪問權限時使用他們。//suid,sgid為備份uid,giduid_t uid, euid, suid, fsuid;gid_t gid, egid, sgid, fsgid;int ngroups; //記錄進程在多少個用戶組中gid_t groups[NGROUPS]; //記錄進程所在的組kernel_cap_t cap_effective, cap_inheritable,cap_permitted;//進程的權能,分別是有效位集合,繼承位集合,允許位集合int keep_capabilities : 1;struct user_struct user;limitsstruct rlimit rlim[RLIM_NLIMITS]; //與進程相關的資源限制信息unsigned short used_math; //是否使用FPUchar comm[16]; //進程正在運行的可執行文件名file system info //文件系統信息int link_count, total_link_count;struct tty_struct tty; NULL if no tty 進程所在的控制終端,如果不需要控制終端,則該指針為空unsigned int locks; How many file locks are being heldipc stuff //進程間通信信息struct sem_undo semundo; //進程在信號燈上的所有undo操作struct sem_queue semsleeping; //當進程因為信號燈操作而掛起時,他在該隊列中記錄等待的操作CPU - specific state of this task //進程的CPU狀態,切換時,要保存到停止進程的task_struct中struct thread_struct thread;filesystem information; 文件系統信息struct fs_struct fs;open file information //打開文件信息struct files_struct files;signal handlers //信號處理函數spinlock_t sigmask_lock;Protects signal and blockedstruct signal_struct sig; //信號處理函數,sigset_t blocked; //進程當前要阻塞的信號,每個信號對應一位struct sigpending pending; //進程上是否有待處理的信號
}
??????3.進程狀態
??????R 運行狀態,S 睡眠狀態, D 狀態深度睡眠狀態,(在該狀態下的進程不能被其他進程喚醒,只有自己可以喚醒自己),T 停止狀態, t 追加狀態, X 死亡狀態, Z 僵尸狀態
??????4.僵尸進程
??????定義:;所謂僵尸進程就是進程處于一個僵死的狀態,即進程已經退出,但其父進程沒有得到子進程的退出信息,此時的進程就會成為一個僵尸進程。
??????來看一段代碼
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>int main()
{pid_t id;id = fork();if(id < 0){perror("fork");exit(0);}else if(id == 0){printf("I am child\n");sleep(1);}else{printf("I am father\n");sleep(15);}return;
}
??????于是看到了系統中出現了一個僵尸進程。在此必須注意,僵尸進程的父進程如果一直不去讀取該進程的信息,則這個進程將會一直處于將是狀態,并且該進程的PCB也將一直被維持,那么就會造成內從泄露。
??????5.孤兒進程
????????孤兒進程就是父進程先于子進程退出,此時的子進程就會變成孤兒進程,那是不是就是說該進程的信息就沒人來讀取嗎?答案是否定的。此時的子進程會被1號init進程領養,于是該子進程就會變成孤兒進程。
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>int main()
{pid_t id;id = fork();if(id < 0){perror("fork");exit(0);}else if(id == 0){printf("I am child\n");sleep(1);}else{printf("I am father\n");sleep(15);}return;
}
??????????
????????監視可以看到并沒有僵尸狀態,則說明子進程退出時的信息被其他進程讀取,進而也說明進程被領養。
??????6.查看系統進程
????????查看系統進程可以用ps,或者top命令來查看
????????
????????其中 PRI 是優先級,數字越小優先級越高,而 nice 是用來修改 PRI 的 PRI(new) = PRI(old) + nice, nice 的取值范圍是 -20 到 19, 創建進程時 PRI 默認是80, 而 nice 默認為 0。
????????進城之間具有競爭性, 系統進程數目眾多, 而 CPU 的資源有限,因此為了能夠高效完成任務,合理競爭相關資源,進程之間就需要有一個優先級,確保CPU正常工作;同時進程在運行期間獨享各自資源,互不干擾,因此進程是具有獨立性的;在多個CPU 的狀況下, 進程之間可以同時工作,因此進程具有獨立性;當只有一個CPU時,為了讓每個進程得以運行,CPU采用進程切換的方式,以確保在一段時間里每一個進程都可以得以運行,因此進程具有并發性。