離職了,交接期也有足夠的時間了,能夠在好好的再看一下APUE,想一想上次詳細的看仍是在兩年以前,雖然中間也偶爾會翻出來看看,可是因爲工做上交集相對比較少一直沒有去細讀一下。如今正好是一段空擋期能夠好好看下書了。設計模式
第八章以前是一些基礎性的東西,若是須要的話能夠在後面的文字中稍微提一下,主要仍是從進程開始吧。進程的出現是必然的,看下計算機發展的過程能夠發現,隨着硬件性能的不斷提高,咱們也在不斷改變軟件的性能,這樣二者的結合才能作到完美。單進程的模式在如今看來是沒法想象的,多個軟件不能並行的運行,只能一個一個的串行的運行,也就是說我在用一個看視頻的時候無法使用瀏覽器進行上網。要是把如今的人拉到當時去感覺一下單進程的話估計會瘋掉。多進程的出現很完美的解決了這些問題。瀏覽器
1.資源對多個進程是可用的。函數
2.物理處理器能夠在多個進程在切換以保證每一個程序都在運行中。性能
3.處理器和IO獲得充分的利用。spa
Linus Torvalds寫的Linux最第一版本,只是打印AAA和BBB,讓多個task同時工做充分理由計算機的硬件。最初的源碼是彙編的咱們也不必去考證。如今的話咱們仍是來看看如今的Linux中關於一些多進程的模型以及IPC的方法吧。設計
1.Linux進程建立之fork, pid_t fork(void)
從函數名字來看是一個很簡單的名字那麼執行這個函數以後作了寫什麼呢?首先子進程獲得一個父進程的副本,這裏的副本包括數據空間,堆和棧的副本,正文段的副本。fork以後子進程不是從main函數開始執行,而是從何父進程相同的位置執行(獲得的父進程的副本里有一個指針指向當前執行的代碼段),因爲子進程沒有執行fork,因此fork函數在克隆子進程,把子進程中返回的進程ID初始化成0。以後他們就是兩個獨立的進程了。指針
無論是進程仍是面向對象中的設計模式,你細細的看的話他的處理過程都來自於生活,感受全部的過程都是在模擬和抽象一我的類具體生活過程,父進程子進程,父類子類,以及各類設計模式,在這裏你多少都能看看到人的痕跡。有時候分析一個複雜的軟件設計的時候咱們能夠從人是怎麼處理相似的過程出發,而後抽象設計出這樣的代碼。code
繼續回到進程相關的東西上,下面是一個簡單的samplecode從這裏的輸出你能夠看到父子進程的棧空間上的數據是相互獨立的。視頻
int var = 88; pid_t pid = 0; if ((pid=fork()) < 0){ printf("fork error"); } else if (pid > 0){ //parent process var += 10; sleep(2); printf("value in parent process:%d\n", var); } else { var -= 10; printf("value in child process:%d\n", var); } return 0;相應的輸出爲:對象
2.1 父進程先於子進程結束
父進程的資源被釋放,當前子進程的父進程設置init進程,這時的子進程也叫作孤兒進程(孤兒進程對系統是沒有危害的)。下面是要給sample code。
pid_t pid = 0; if ((pid=fork()) < 0){ printf("fork error"); } else if (pid > 0){ //parent process sleep(1); //child process execute first } else { printf("befor parent exit ppid = %d\n", getppid()); sleep(5); printf("after parent exit ppid = %d\n", getppid()); } return 0;相應的輸出爲:
2.2 子進程先於父進程結束
子進程的資源被釋放,但佔用一個管理節點(用於父進程使用wait函數回收)。子進程給父進程發送SIGCHILD信號,若是父進程沒有使用wait函數進行善後處理,那麼這個進程就成了殭屍進程,他就永遠的佔用了系統的一些資源。下面是一個簡單的sample code。使用ps能夠查看到沒有被回收的子進程的狀態是Z(zombie)。
相應的輸出爲:pid_t pid = 0; if ((pid=fork()) < 0){ printf("fork error"); } else if (pid > 0){ //parent process sleep(100); } else { printf("pid = %d\n", getpid()); } return 0
相應的若是使用wait函數了會是一個怎樣的處理呢?
若是一個進程已經終止,而且是一個殭屍進程,則wait當即返回並取得該進程的狀態。不然wait使調用者阻塞直到一個子進程終止。若是有多個子進程的話能夠考慮waitpid(pid_t pid, int *status, int option)。