1. 程式人生 > >多程序相關係統呼叫

多程序相關係統呼叫

1、fork函式
#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);
  • 函式每次呼叫都返回兩次,在父程序中返回子程序ID,在子程序中返回0。呼叫失敗是返回-1,並置errno。
  • fork函式複製當前程序,在核心程序表中建立一個新的程序表項,新程序很多屬性與原程序相同,例如堆疊指標,標誌暫存器等,也有屬性不同,例如PID,PPID,訊號點陣圖(原程序設定的訊號處理函式不再對新程序起作用)。
  • 寫時複製
  • 父程序中開啟的檔案描述符,在子程序中也是開啟的,且檔案描述符的引用計數加1

2、exec系列系統呼叫

#include<unistd.h>
extern char** environ;
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, char* const argv[]);
int execvp(const char* file, char* const argv[]);
int execve(const char* path, char* const argv[], char* const envp[]);
  • exec函式功能是替換程序映像
  • path引數指定可執行檔案的完整路徑
  • file引數可以接受檔名,檔案的具體位置則在環境變數PATH中搜索
  • arg接收可變引數,argv接收引數陣列,它們都會被傳遞給新的程式的main函式
  • envp引數用於設定新程式的環境變數,如果未設定,則使用全域性變數environ指定的環境變數
  • exec函式一般不返回,出錯才返回-1,並設定errno。如果沒有出錯,exec函式之後的程式碼不會執行

3、wait和waitpid函式

    在多程序中,父程序一般是要跟蹤子程序的退出狀態的,所以,在子程序執行結束時,核心並不會立即釋放該程序的程序表表項,而是要等待父程序對該子程序退出資訊的查詢後才釋放。

    殭屍程序有兩種情況,其一,子程序結束執行,而父程序還沒有讀取其退出狀態之前,此期間子程序處於殭屍狀態。其二,父程序先結束執行,而子程序繼續執行,此時子程序將由init程序接管,則父程序退出之後,子程序退出之前,子程序處於殭屍狀態。殭屍狀態的程序會佔據著核心資源。wait和waitpid函式就是用來避免殭屍程序的產生的,在父程序中呼叫,以等待子程序退出,並獲取退出資訊。

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* stat_loc);
pid_t waitpid(pid_t pid, int* stat_lic, int options)
  • wait函式將阻塞程序,直到某個子程序結束為止,返回子程序的pid,並將退出狀態資訊儲存於stat_loc引數指向的記憶體中。
  • waitpid函式只等待有pid引數指定的子程序,如果pid為-1,則等待任一子程序退出。options引數取值為WNOHANG可控制函式為非阻塞的,此時pid指定的子程序如果沒有結束或意外終止,則立即返回0,如果子程序正常退出,則返回該子程序的PID。waitpid函式呼叫失敗返回-1,並設定errno。

    對於非阻塞的呼叫,在事件已經發生時再執行,效率才會更高,所以對於waitpid函式,應該在某個子程序已經退出了,再呼叫它。SIGCHLD訊號則是在一個程序退出時傳送給其父程序的訊號,所以可以在父程序中捕獲SIGCHLD訊號,並在訊號處理函式中呼叫waitpid函式。