1. 程式人生 > >Linux_程序的建立

Linux_程序的建立

之前瞭解了程序的相關基礎知識,現在來了解一下程序的實際應用

1程序建立的一般過程:

    1)給新程序分配一個識別符號。核心中分配一個PCB

    2)複製父程序的環境

    3)分配程式.資料.棧等記憶體資源

    4)複製父程序的地址空間的內容

    5)將程序置成就緒狀態,放入就緒佇列

2.fork

    1)首先呼叫fork之前,要加標頭檔案#include <unistd.h>

    2)函式原型 pid_t fork(void)

    3)返回值:子程序返回0,父程序返回子程序id,出錯返回-1,建立子程序失敗。

    4)fork呼叫失敗原因:系統內有太多程序或者實際使用者的程序數超過了限制。

下面驗證一下fork()的返回值 


圖中箭頭和數字代表程式執行步驟

執行結果:


解釋一下:程式開始執行,首先進入父程序,在呼叫fork之前,先輸出父程序的id,執行fork後,父子程序會從fork之後的程式碼來繼續執行,繼續執行父程序,pid接受fork返回值,父程序返回子程序id,然後進入子程序,pid接收fork返回值,子程序返回0。

注意:

1)父子程序執行先後順序不確定

2)呼叫fork以後,父子程序交替執行。

3)如果父程序先死,子程序就變成孤兒程序,孤兒程序會被1號程序收養。

4)如果子程序先死,子程序就會變成殭屍程序(清理殭屍程序,用wait函式)

另一種執行步驟:(fork後先執行子程序)


3.子程序與父程序

    子程序繼承父程序:

        地址空間,程序上下文,程序堆疊,記憶體資訊,檔案描述符(父程序開啟的檔案),訊號設定,程序排程優先順序,當前路徑,根路徑,控制終端,程序組,資源限制情況...

    子程序不繼承父程序:

        1>父程序的鎖子程序不繼承

        2>父程序id子程序不繼承

        3>父程序未決的訊號子程序不繼承

        4>父程序的鬧鐘子程序不繼承

    子程序與父程序的關係:

        子程序以父程序為模板,首先複製父程序的PCB,並進行簡單修改;複製父程序的虛擬地址空間(頁表)對應的實體記憶體會進行寫時拷貝。

4.vfork

    1)首先呼叫vfork之前,要加標頭檔案#include <unistd.h> 和 #include <sys/types.h>

    2)函式原型 pid_t vfork(void)

vfork 與fork的區別

    1)vfork用於建立一個子程序,創建出來的子程序和父程序共用同一塊虛擬空間。但fork出來的子程序具有獨立的地址空間。

    2)vfork出來的子程序一定會先執行,父程序會掛起,一直掛起到子程序呼叫了_exit或exec父程序才會繼續執行。

例項:

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>

 int glob=100;

 int main(void){
        pid_t pid;

        pid = vfork();
        if(pid==-1) perror("fork"),exit(1);
        else if(pid ==0) {//子程序
                sleep(3);
                glob=200;
                printf("child glob %d \n",glob);
                exit(0);
                }
        else { //父程序
                printf("parent glob %d \n",glob);
        }
        return 0;
}

執行結果:


解釋一下:子程序先執行,修改了glob變數的值,呼叫了exit,父程序排程執行,父子程序共用一塊虛擬記憶體,所以glob的值也被更改。