【APUE】進程控制

本文介紹進程控制,包括創建進程,執行程序和進程終止

1.進程標識符

    每一個進程都有一個非負整數表示的唯一進程ID,pid。雖然pid是唯一的,但是可以重複使用,當進程結束的時候,
    其pid就可以在次使用了。
    系統中常有一些專用進程:
    0:通常是調度進程,常稱爲交換進程,因爲不使用磁盤中的任何程序,所以又稱爲系統進程。
    1:通常是init進程
    下面的函數返回進程標識符
    #include <unistd.h>
    pid_t getpid(void);
    //返回調用進程的pid
    pit_t getppid(void);
    //返回調用進程的父進程pid
    uid_t getuid(void);
    //返回調用進程的實際用戶id
    uid_t geteuid(void);
    //返回調用進程的有效用戶id
    gid_t getgid(void);
    //返回調用進程的實際組id
    gid_t getegid(void);
    //返回調用進程的有效組id

2.fork函數

    創建一個新進程
    #include <unistd.h>
    pid_t fork(void);
    //子進程中返回0,父進程返回子進程pid,出錯返回-1
    子進程是父進程的副本,子進程獲得父進程的數據空間,堆和棧的副本,父子之間不共享這些存儲區部分
    父子進程共享正文段,而正文段通常是隻讀的。也就是說對子進程進行操作,對父進程沒有任何影響。
    (現代的處理方法:使用到了寫時複製的技術,存儲區內容父子共享,併爲只讀,當父子進程中任一要去寫的時候,
    內核就爲其修改的那個部分製作一個副本,通常是虛擬存儲器系統的一頁)

3.vfork函數


    創建一個進程,但是與fork有區別
    #include <unistd.h>
    pid_t vfork(void);
    //子進程中返回0,父進程返回子進程pid,出錯返回-1
    此時,子進程和父進程共享資源,當對子進程進行操作的時候,會影響到父進程。vfork之後通常接着exec。
    vfork保證子進程先運行,他在調用了exec或者exit之後父進程才能被調度運行。

4.exit函數

    在說明fork函數時,顯而易見,子進程是在父進程內調用fork後生成的。子進程在終止的時候會將把自己的終止狀態
    返回給父進程。如果父進程在子進程終止之前終止,對於父進程的所有子進程他們的父進程都改爲init進程。我們稱
    這些進程由init領養。其操作的大體過程如下:
        在一個進程終止的時候,內核逐個檢查所有活動進程,以判斷它是否是正要終止進程的子進程。如果是,
        則將該進程的父進程ID更改爲1.這種處理方式保證了每個進程都有一個父進程。
    如果子進程在父進程之前終止,內核就爲每個終止子進程保存了一定量的信息,所以當終止進程的父進程調用wait
    或waitpid時,可以得到這些信息。這些信息至少包括進程ID,進程的終止狀態,以及該進程使用的CPU時間總量。
    內核可以釋放終止進程所使用的所有存儲區,關閉其所有的打開文件。但是一個已經終止,而父進程尚未對其進行
    善後處理的進程被稱之爲僵死進程。
    當init的子進程終止的時候,init進程會自動調用wait函數取得其終止狀態。防止了系統中有很多僵死進程。

5.wait和waitpid函數

    當調用這兩個函數的時候:
        如果其所有子進程都還在運行,則阻塞;
        如果一個子進程已經終止,正等待父進程獲取其終止狀態,則取得該子進程的終止狀態立即返回;
        如果沒有任何子進程,則會出錯.
    #include <sys/wait.h>
    pit_t wait(int *statloc);
    pit_t waitpid(pid_t pid, int *statloc, int options);
    在一個子進程終止前,wait使其調用者阻塞,而waitpid有一個選項,可以使調用者不阻塞。
    waitpid並不等待在其調用之後的第一個終止子進程,它有若干個選項,可以控制它所等待的進程。
    如果第一個子進程已經終止,並且是一個僵死的進程,wait立即返回並取得該子進程的狀態,否則wait使其調用者阻塞
    直到一個子進程終止。若調用者阻塞而且它有多個子進程,則當有一個子進程終止的時候,wait函數就立即返回。
    statloc是一個整型指針,如果這個指針不爲空,則存儲子進程的狀態
    pid參數的作用如下:
    pid == -1    等待任一子進程,此時,與wait等效
    pid > 0        等待其進程ID與pid相等的子進程
    pid == 0    等待其組ID等於調用進程組ID的任一子進程
    pid < -1    等待其組ID等於pid絕對值的任一子進程
    options參數使我們能進一步控制waitpid操作,此參數可以爲0
    常量        說明
    WCONTINUED    若實現支持作業控制,那麼由pid指定的任一子進程在暫停後已經繼續,但其狀態尚未報告,
            則返回其狀態
    WNOHANG        若由pid指定的子進程並不是立即可用的,則waitpid不阻塞,此時其返回值爲0
    WUNRTACEO    若某實現支持作業控制,而由pid指定的任一子進程已處於暫停狀態,並且其狀態自暫停以來
            還未報告過,則返回其狀態。WIFSTOPPED宏確定返回值是否對應於一個暫停子進程

6.waitid函數

    此函數類似與waitpid,但是提供了更多的靈活性
    #include <sys/wait.h>
    int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
    //成功返回0,出錯返回-1
    使用單獨的參數表示要等待的子進程類型id的值與idtype的值有關,以下列出idtype的類型:
        P_PID    等待一個特定的進程,id包含要等待進程的進程id
        P_PGID    等待一個特定進程組的任一子進程,id包含等待進程組的進程組id
        P_ALL    等待任意子進程,乎略id
    options參數:
        WCONTINUED    等待一個進程,它以前曾被暫停,此後有繼續執行,但其狀態未返回
        WEXITED        等待已經退出的進程
        WNOHANG        如無可用的子進程退出狀態,立即返回而非阻塞
        WNOWAIT        不破壞進程退出狀態。該子進程退出狀態後可由後續的wait,waitpid或waitid調用獲取
        WSTOPPED    等待一個進程,它已經暫停,但其狀態尚未報告

7.競爭條件

    當多個進程都企圖對共享數據進行某種處理,而最後的結果由取決於進程運行順序的時候,我們認爲發生了競爭

8.exec函數

    當進程調用exec函數的時候,進程執行的程序完全替換爲新的程序,而新程序從其main函數開始執行。
    exec函數只是用一個全新的程序替換了當前進程的正文,數據,堆和棧段。
    #include <unistd.h>
    int execl(const char *pathname, const char *arg0, .../* (char *)0 */);
    int execv(const char *pathname, char *const argv[]);
    int execle(const char *pathname, const char *arg0, ... /* (char *)0, char *const envp[] */);
    int execve(const char *pathname, char *const argv[], char *const envp[]);
    int execlp(const char *filename, const char *arg0, .../* (char *)0 */);
    int execvp(const char *filename, char *const argv[]);
    //出錯返回-1,成功不返回
    前4個函數將路徑名作爲參數,後兩個函數將文件名作爲參數,如果filename含有/,則表示路徑名
    否則就按照環境變量所指定的目錄中搜索可執行文件
    execlp和execvp的filename可以是shell腳本
    其他參數爲新程序的命令行參數
    6個函數中,字母p表示該函數取filename爲參數,字母l表示該函數取一個參數表,與字母v互斥,v表示該函數取一個envp[]數組,而不使用當前環境

9.更改用戶ID和組ID


    #include <unistd.h>
    int setuid(uid_t uid);
    int setgid(gid_t gid);
    //成功返回0,出錯返回-1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章