目錄
一、什麼是進程
- 進程是程序執行的動態過程
- 進程是資源管理的最小單位(線程是系統調度的最小單位)
- 在linux中,我們可以通過 file 文件名 得知一個文件的文件類型,以一個可執行程序爲例,如下圖所示
- 由上面可以得知,大多數的可執行程序的格式爲ELF格式。那麼一個可執行程序,是如何被linux運行起來的呢?如下圖所示
當ELF格式的可執行程序被執行的時候,程序被加載到內存中執行,此時內核產生了一個名爲task_struct{}的結構體來表示與管理這個進程。
其中:
- .text 段存放代碼,只讀並且共享,這段內存在程序運行期間不會被釋放
- .data段存放已經初始化的全局變量和已經初始化的static變量,可讀可寫,這段內存在程序運行期間一直存在。
- .bss段存放未初始化的全局變量和未初始化的static變量,可讀可寫,這段內存在程序運行期間一直存在。
- .rodata段存放只讀數據(如:字符串常量)
二、進程的“生老病死”
- 進程從“誕生”到“被回收”的一系列過程狀態轉換圖,如下圖所示
一般流程爲:
- 父進程調用fork函數,生成子進程(使用fork產生的子進程與父進程一模一樣,並且子進程會從fork返回值後的下一條邏輯語句開始執行)
- 子進程運行結束,執行exit退出
- 父進程使用wait或者waitpid回收子進程的資源
三、進程相關函數
1、子進程的創建
- pid_t fork(void);
2、進程的退出
- void exit(int status);//清空I/O緩衝區之後,才退出進程 ,在多進程裏面,進程正常退出需要用exit(0)
- void _exit(int status);//直接結束進程,不做清理的操作,直接進入到內核。
- return 0;// return是c語言裏面的一個關鍵字。如果是在調用函數的時候,是出棧的處理。如果是在main函數裏面,是結束進程
3、子進程資源的回收(如果子進程資源沒有被回收,則會變成殭屍進程,佔用系統資源)
- pid_t wait(int *stat_loc);//阻塞
- pid_t waitpid(pid_t pid, int *stat_loc, int options);//可阻塞 或者 無阻塞
4、在一個進程中調用另外一個進程(system調用其他進程是通過shell調用其他進程,本程序進程與被調用的進程之間沒有關係。)
- int system(const char *command);
- 如:system("ls -l")、system("./main")
5、子進程中運行其他程序(程序的替換,覆蓋原有代碼)
其中:execl 中的l 與execv 中的v 的含義
l: list 列表,把參數一一列表寫在參數裏面,寫完之後,需要加一個NULL。
v: vector 向量、數組,把參數寫進去。
- int execl(const char *path, const char *arg, ... , /* (char *) NULL */);
- int execlp(const char *file, const char *arg, ... , /* (char *) NULL */);
- int execle(const char *path, const char *arg, ... , /*, (char *) NULL, char * const envp[] */);
- int execv(const char *path, char *const argv[]);
- int execvp(const char *file, char *const argv[]);
- int execvpe(const char *file, char *const argv[], char *const envp[]);