進程:系統進行資源調度和分配的的基本單位,實現了操作系統的併發。
1.進程的資源組成:
(1).內核空間進程資源PCB:記錄着包括進程控制塊本身以及打開的文件表項,當前的目錄、當前終端信息、線程基本信息、可以訪問的內存地址空間、PID/PPID等各種信息。 內核通過PCB可以訪問到進程的所有資源,用戶訪問時需要使用系統調用函數;
(2).用戶空間進程資源:進程的代碼段、數據段、堆棧以及可以共享訪問的內存空間,進程可以直接訪問,在進程退出時自動釋放;
(3).Fork創建新的進程,extern _pid_t fork(void ); 當pid=0時子進程,pid>0時爲父進程,子進程複製父進程用戶空間的所有數據(代碼段,數據段,bss段,堆棧),以及內核空間絕大多數的信息,從而成爲一個獨立的實體。 而對於內核空間中打開的文件描述符fd所對應的文件表項則以共享的方式一起使用(父進程打開一個文件向其中寫入字符,子進程打開文件後會接着文件的偏移,繼續寫入);
(4).Vfork創建新的進程與父進程共享代碼段和數據段。
2.進程的狀態:
(1).就緒態:TASK_RUNNING,進程申請到了除CPU以外的其他所有資源;
(2).等待狀態(可以被中斷打斷):TASK_INTERRUPTIBLE,處於等待的隊列,等待資源有效時被喚醒,可以被中斷喚醒;
(3).等待狀態(可以被中斷打斷):TASK_UNINTERRUPTIBLE,處於等待的隊列,不可以被中斷喚醒;
(4).僵死狀態:TASK_ZOMBLE,進程用戶空間釋放,PCB等待父進程的釋放;
(5).停止狀態:TASK_STOPPED,收到SIGSTOP等信號被外部程序暫停,再次被允許時繼續執行(SIGCONT信號)。
3.殭屍進程:
(1)原因:進程調用了exit命令結束了自己的進程,子進程先於父進程退出,殭屍進程放棄了大部分的內存空間,代碼段、數據段等全部銷燬,不能再被調度,但因爲其PCB中還保留了很多關於它的退出信息供其他的進程採集,所以它的PCB也不會被摧毀,這樣就造成了內存的浪費問題;
(2).處理方法:①waitpid(-1,NULL,WNOHANG) 函數用來等待子進程結束; ②讓父進程等待子進程,在子進程工作完之後父進程再工作。子進程在銷燬退出時會給父進程發送一個SIGCHLD信號,父進程收到信號之後可以使用wait()函數對其進行處理; ③兩次使用fork函數,使緊跟的子進程直接退出,使得孫子進程成爲孤兒進程,從而init進程將負責清除這個孤兒進程。
(3).Ps查看時進程的狀態信息爲:<defunt > 或 <z>;
4.孤兒進程:
(1)原因:父進程先於子進程退出,導致子進程被init進程收養的進程,而init進程在退出時會回收其內核空間資源。
(2)在使用ps -aux | grep pid時其父進程pid爲1.
5.守護進程:
(1)一種在後臺運行的特殊進程,脫離於終端,無法被終端中產生的任何信號打斷,執行過程產生的信息不在終端顯示,週期性的執行任何和處理事件。(服務器常用);
(2)守護進程在關閉終端控制檯時不會受影響;
(3)守護進程的會話組和當前目錄,文件描述符都是獨立的;
(4)使用ps -axj查看守護進程。
守護進程的啓動:①系統啓動時由啓動腳本/etc/init.d腳本運行; ②利用inetd超級服務器啓動,如telnet;③由corn命令定時啓動的進程以及在終端使用nohup命令驅動的進程。
6.後臺進程:
將那些不需要交互,沒有輸出的進程的進程放在後臺運行;
相關命令:①將命令放在後臺運行 xxx命令 + & ;②查看後臺進程:jobs ③將程序放到後臺運行:ctrl + z; ④將掛起的進程放在後臺運行:bg + 進程名。
7.進程間通信方式:
管道、系統IPC(包括消息隊列、信號量、信號、共享內存等)、以及套接字socket。
(1)管道:
①無名管道PI PE:它是半雙工的(即數據只能在一個方向上流動),臨時存在(在完成通信之後自動消失); 具有固定的讀端和寫端; 只能用於具有親緣關係的進程之間的通信(也是父子進程或者兄弟進程之間); 可以看成是一種特殊的文件,對於它的讀寫也可以使用普通的read、write等函數,但它不是普通的文件,並不屬於其他任何文件系統,並且只存在於內存中。
②有名管道FIFO:FIFO可以在無關的進程之間交換數據; FIFO有路徑名與之相關聯,它以一種特殊設備文件形式存在於文件系統中。
(2)系統IPC:
①消息隊列:消息隊列是消息的鏈接表,存放在內核中。一個消息隊列由一個標識符(即隊列ID)來標記。 (消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等特點)具有寫權限得進程可以按照一定得規則向消息隊列中添加新信息;對消息隊列有讀權限得進程則可以從消息隊列中讀取信息; 特點:消息隊列是面向記錄的,其中的消息具有特定的格式以及特定的優先級;消息隊列獨立於發送與接收進程。進程終止時,消息隊列及其內容並不會被刪除;消息隊列可以實現消息的隨機查詢,消息不一定要以先進先出的次序讀取,也可以按消息的類型讀取。
②信號量semaphore:信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。信號量用於實現進程間的互斥與同步,而不是用於存儲進程間通信數據。特點:信號量用於進程間同步,若要在進程間傳遞數據需要結合共享內存; 信號量基於操作系統的 PV 操作,程序對信號量的操作都是原子操作; 每次對信號量的 PV 操作不僅限於對信號量值加 1 或減 1,而且可以加減任意正整數; 支持信號量組。
③信號signal:信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
④共享內存(Shared Memory):它使得多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數據得更新。這種方式需要依靠某種同步操作,如互斥鎖和信號量等。 特點:共享內存是最快的一種IPC,因爲進程是直接對內存進行存取; 因爲多個進程可以同時操作,所以需要進行同步; 信號量+共享內存通常結合在一起使用,信號量用來同步對共享內存的訪問。
(3)套接字SOCKET:
socket也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同主機之間的進程通信。