進程函數 簡單描述一下關於進程的函數,主要有fork調用、exec調用、exit調用、wait調用和sleep調用。 fork調用 所需頭文件 #include <unistd.h> //標準函數庫 #include <sys/types.h> //提供系統調用的標誌 函數原型 pid_t fork ...
進程函數
簡單描述一下關於進程的函數,主要有fork調用、exec調用、exit調用、wait調用和sleep調用。
fork調用
所需頭文件
#include <unistd.h> //標準函數庫
#include <sys/types.h> //提供系統調用的標誌
函數原型
pid_t fork(void); //創建子進程時,複製父進程上下文
pid_t vfork(void); //創建子進程時,不複製父進程上下文
返回值
成功:返回兩個值。子進程返回0,父進程返回子進程ID。
失敗:-1
fork函數是Unix/Linux操作系統中用於創建子進程的函數。當調用fork()函數時,操作系統會創建一個與原進程幾乎完全相同的新進程。
- 操作系統接收到fork()函數調用後,會複製父進程的所有資源(包括代碼、數據、堆棧等)到子進程。
- 子進程擁有與父進程完全相同的記憶體映像,但是具有獨立的地址空間。
- 子進程從fork()函數的返回處開始執行,而父進程則繼續在原來的位置執行。
- fork()函數返回兩次,一次返回給父進程,一次返回給子進程。在父進程中,fork()函數返回子進程的PID;在子進程中,fork()函數返回0。
- 父進程和子進程是相互獨立的,它們有不同的PID,但是它們共用相同的代碼段、數據段和堆棧段。
- 父進程可以通過獲取子進程的PID,並使用系統調用wait()等待子進程的結束,從而獲得子進程的返回狀態。而子進程可以通過系統調用exec()來執行新的程式,從而創建一個全新的進程。
代碼運行結果
子進程正在工作:
子進程PID是11718
父進程PID是11713
父進程正在工作:
父進程PID是11713
子進程PID是11718
由結果而知,父進程調用子進程後,父進程由內核狀態轉為用戶狀態,子進程開始執行並輸出信息。然後子進程調用exit()函數進入僵死狀態。父進程由用戶狀態重新回到內核狀態並輸出信息。最後父進程等待子進程結束,父進程結束。
exec調用
所需頭文件
#include <unistd.h> //標準函數庫
函數原型
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, const * const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
返回值
成功:不返回
失敗:-1
exec函數以新進程代替原進程,但PID保持不變,因此exec系統調用實際上沒有創建新進程,只是用一個全新的程式替代了當前進程的代碼、數據、堆棧。
exit調用
所需頭文件
#include <unistd.h> //標準函數庫
函數原型
void exit(int status); //合適時釋放
void _exit(int status); //立即釋放
返回值
不返回
exit和_exit系統調用都是用於終止一個進程。(exit比較安全)
系統調用exit()將進行一些上下文清理工作,例如關閉文件描述符、釋放所有占用的資源、清空緩衝區等。進程執行exit系統調用後,linux內核將刪除進程的上下文,但保留進程表項,進程處於僵死態。等待父進程回收資源,再刪除進程表項的內容,釋放進程PID。
系統調用_exit()立即終止發出調用的進程,不會刷新輸入輸出緩衝區(因此進程結束前必須自己刷新緩衝區,或改用exit()系統調用)。所有屬於該進程的文件描述符都關閉。如果該進程擁有子進程,那麼父子進程關係被轉到init進程上。被結束的進程將收到來自子進程的僵死信號SIGCHLD。如果被結束的進程在控制台或終端上運行,shell程式將收到SIGHUP信號。參數status是返回給父進程的狀態值,父進程可通過wait系統調用獲得。status只有最低1個位元組能被父進程讀取(實際值範圍:0~255)
wait調用
//所需頭文件
#include <sys/wait.h>
//函數原型
pid_t wait(int *status);
//返回值
成功:退出的子進程PID
失敗:-1
//處理子進程退出狀態值的巨集
WIFEXITED(status):如果子進程正常退出,則該巨集為真
WEXITSTATUSA(status):如果子進程正常退出,則該巨集獲取子進程的退出值
wait調用用於父進程等待子進程的終止(阻塞當前進程,直到子進程終止),如果當前進程沒有子進程,會立即返回一個錯誤。
sleep調用
//所需頭文件
#include <unistd.h>
//函數原型
unsigned int
//返回值
sleep調用用於使進程主動進入睡眠狀態。