這一章內容是Process的基礎準備篇章。這一章的內容都是基於C Programm爲例子。函數
(一)進程開始:spa
kernel → C start-up rountine → main functionorm
其中C start-up rountine作的事情中包括:得到command-line arguments & environment進程
好像還有其餘的事情,後面再說。ip
(二)進程結束:資源
五種normal termination方式:作用域
1. return from main字符串
2. exitget
3. _exit _Exitit
4. 從start routine調用的last pthread裏面return
5. 在最後一個pthread中調用pthread_exit
三種abnormal termination方式:(這三種方式先不學)
1. abort
2. receipt of a signal
3. response of the last pthread to a cancellation request
註冊進程退出時執行「鉤子函數」:atexit
基於stack結構實現的,因此用atexit註冊的函數在進程exit的時候是reverse order執行的(跟Chapter11提到的進程清理函數也相似)
這部分的代碼比較直觀,看書上P202 Figure7.3代碼便可。
APUE 英文3版201頁Figure7.2是個比較綜合的圖,很好闡述了進程開始和結束的各類路徑以及作的事情:
簡單來講:
1. return或exit :先調用各類exit handler以及standard I/O cleanup;再調用_exit或_Exit
2. 若是是直接_exit或_Exit就直接強行退出進程,一步到位,不會調用各類exit handler和Cleanup等了
(三)Command-Line Arguments
沒有什麼特別解釋的 就是main傳入兩個參數:
1. int argc:參數個數
2. char *argv[]:以字符串形式傳入的參數
argv[0]永遠是命令自己,從argv[1]開始是真正傳入程序的參數
(四)Environment List
以前main的參數中是有這個的;可是後來發現這東西的用途太多了,地位就升級了,就給他專門搞了一些內置的函數去操做
(五)Memory Layout of a C program
重點都在P206的Figure7.6上面。
地址由高到低依次是:
第一部分:Command-Line arguments & environment variables
第二部分:stack(棧)(調用函數的stack frame在這裏,函數返回以後,這部分資源就可能瞬間被其餘內容覆蓋了)
第三部分:留白 (stack能夠向下grow,佔用這塊留白;heap能夠向上grow,佔用這塊留白)
第四部分:heap(堆)(提供動態分配的空間:malloc;若是忘了free,就memory leak了)
第五部分:uninitialized data (沒有初始化的全局變量)
第六部分:initialized data (初始化的全局變量)
第七部分:text segment(包括CPU可執行的machine instructions)
其中,只有6、七兩部分是存在於program file中的;五貌似也像在program file中的,其實不是的,是由kernel設置爲0的。
(六)Shared Libraries、(七)Memory Allocation留之後用到再看
(八)Environment Variables
因爲Environment Variables的地位提升了,所以有三個函數能夠改環境變量:
1. putenv
2. setenv
3. unsetenv
這裏有兩點須要注意下:
1. 就是這個簡單的Environment Variables,爲何要搞這樣幾個複雜的函數去設置、修改?回想Memory Layout of a C program,最上面那塊大小是定死的:若是EV比原來短還好,比原來長,或者動態增長,就須要利用heap空間了。這就涉及到一些麻煩事情。詳情書上寫的挺好。
2. 進程中設定EV的做用域:在當前進程設置的EV,只對當前進程以及其子進程有效,不影響其餘進程。
(九)setjmp和longjmp
代碼都在書上,很直觀就不粘上來了。
Goto是在同一個函數中跳轉(某個stack frame內);setjmp和longjmp負責在一個進程的函數間跳(誇若干個stack frame)
有幾點須要注意:
1. setjmp設定跳回到哪,longjmp負責跳,用jmp_buf類型的變量來協調兩者,跳到哪。
2. 通一個setjmp能夠從不一樣地方longjmp回來
3. f1() { setjmp; f2(){f3(longjmp;)}} 若是從f3中跳回f1,則stack中f2和f3的stack frame都無效了(即不歸f2和f3是換了,可能迅速被其餘佔用了)
4. 仍是3中的例子,若是longjmp回到f1中了,那麼f1中變量的狀態呢?受到執行完f1和f2以後的影響,仍是保存以前的狀態呢?答案是不必定,尤爲是autmatic register變量,更是不必定了。這裏比較好的辦法是,把變量設成volatile的,這樣即便longjmp回來,變量確定是受到f2和f3的影響後的值,不會出現不肯定狀態
(十)getrlimit & setrlimit
涉及到進程佔用資源的分配,後面再看。