引入地址空間
靜態變量和棧空間變量
靜態變量默認是被初始化的
存放在初始化和為初始化空間中
static已經變成了全局變量
命令行參數和環境變量的增長方向
這里觀察的是
命令行參數
和環境變量
的地址
觀察命令行和環境變量表的地址


進程地址空間
如果他們是同一塊兒空間,為什么打印的結果卻不一樣呢,我們知道肯定是父進程先跑完,在子進程進程輸出的時候a應該是1才對——我們看到的只是
虛擬地址空間
1.
子進程是父進程的拷貝
,(父子進程代碼和數據是共享的,只有在數據進行改變時才進行寫時拷貝
,子進程繼承父進程的pcb里的大部分內容,地址空間,頁表,并且繼承的時候每個頁表對應的權限默認為只讀的狀態)他們通過頁表進行映射到物理內存
,物理內存由操作系統進行管理
2.因為進程之間是獨立的,他們本來對應的是相同的物理內存,但是當有一方進行改變
的時候,就需要將發生改變的那一方進行拷貝(寫時拷貝
),更改頁表的指向,指向新的物理空間
頁表是有權限的
對數據的權限限制有r,w,rw,一般默認為r
字符串存在常量區,權限是只讀的,操作系統檢測到要修改變量,就會產生報錯
加const是為了增強代碼的安全性,錯誤早發現早處理
在父進程數據拷貝給子進程的時候,會將頁表權限rw->r,因為子進程是父進程的拷貝,頁表也會單獨有一份,父進程和子進程的頁表都會發生改變;當其中有一方進行修改數據,但是檢測到頁表對應的數據是只讀的,此時os將介入,
重新開辟空間,將原來的數據拷貝過來,再進行修改
,完成后權限就會到了rw(缺頁中斷)
進程終止
進程退出狀態:
1:代碼執行完,結果正確
2:代碼執行完,結果錯誤
3:代碼沒執行完,進程異常
只有代碼執行完的退出結果才是有意義的
主函數退出——退出碼
進程終止會有一個返回值(return)——表示退出情況,0表示成功,非0表示失敗發生錯誤
使用echo $?
觀察最后一次退出情況
第一次:139表示出錯
第二三次:0表示正常退出
因為這個命令記錄的是最后一次的退出情況,我們明白命令也是一種程序,echo是正常運行的,所以返回0
其他函數退出——錯誤碼
調用庫函數
,錯誤碼錯誤碼保存在errno
調用自己的函數
,普通函數的返回值一般表示的是函數的結果,特殊情況下,錯誤碼需要自己設置
通過errno的方式觀察庫函數的錯誤碼
進程異常
本質:收到
異常信號
每種信號都是一個宏,每個信號都是不一樣的
exit & _exit
exit是庫函數
_exit是系統調用
exit中的參數表示返回的退出碼
_exit不會刷新緩沖區
exit會刷新緩沖區
證明緩沖區不是在系統中的
進程等待
wait
等待
任意一個進程
父進程等不到就卡死
我們能看到,父進程一直在等待,子進程一直在運行
waitpid
等待特定的pid
exit的參數是1可是為什么status返回的是256呢
status存的信息是錯誤碼+信號
父進程和子進程
fork之后
誰先運行取決于調度器