linux程式設計之程序控制

2021-08-14 15:53:32 字數 4095 閱讀 8776

(一)fork

#include pid_t fork(void);
返回值:有兩個,乙個是子程序的id,另乙個為零。當返回值為0時,進入子程序,大於0進入父程序,返回-1時建立程序錯誤。子程序與父程序的比較:

(1)子程序與父程序的程序id不同。且父程序id不同。

(2)記憶體布局: 子程序是父程序的副本,其中子程序的資料空間,堆,棧是父程序的副本,但是共享真正文段。

(3)執行順序:子程序與父程序執行順序不確定,取決於核心所使用的排程演算法。

(4)檔案共享:父程序所有開啟的檔案描述符都會賦值到子程序,父程序與子程序每個相同的開啟檔案描述符共享乙個檔案表項。即子程序操作檔案直接影響父程序對該檔案的操作,最明顯的是檔案偏移量收到影響。其圖如下所示:

例如:

#include #include #include int main()

else if( pid == 0 )

wait();

printf("parent: x = %d y = %d\n",x,y);

return 0;

}

fork的使用場景:

(1)父程序希望複製自己,使得父程序和子程序同時執行不同的**段,即在網路服務中是最常見的,父程序等待客戶端的服務請求,當請求到來時,父程序fork乙個子程序來處理子程序的請求,這時父程序可以繼續等待下乙個服務請求。

(2)使得子程序執行乙個不同的程式,需要fork乙個子程序,在此子程序中執行exec執行新的程式。

(二)vfork函式

#include #include pid_t vfork(void);
返回值為:與fork幾乎相同與fork函式的不同:

(1)vfork一般是建立乙個程序來執行exec函式,即執行乙個新的程式。

(2)vfork中,子程序不將父程序的位址空間完全複製到子程序中,其子程序在父程序空間中執行。

(3)vfork保證子程序先執行,父程序等待子程序執行完成後在再執行。

(4)vfork子程序的資源與父程序是共用的,因此父程序中變數經過子程序的對其的改變則父程序也會改變。

例如:

//注意與上個fork的例子進行比較

#include #include #include int main()

else if( pid == 0 )

wait();

printf("parent : x = %d y = %d\n",x,y);

return 0;

}

(三)wait函式
#include #include pid_t wait(int *status);
該函式的都是等待子程序的退出,如果成功返回退出程序的id,如果出錯返回-1。

(1)呼叫wait函式

(2)獲得終止狀態

例如:

#include #include #include #include void pr_exit(int status)

else if( wifsignaled(status) ) //判斷該子程序是否異常終止

else if( wifstopped(status) )//子程序暫停

}int main()

else if( pid == 0 )

if( wait(&status) != pid )

pr_exit(status);

if( ( pid = fork()) == -1 )

else if( pid == 0 )

if( wait(&status) != pid )

pr_exit(status);

if( ( pid = fork()) == -1 )

else if( pid == 0 )

if( wait(&status) != pid )

pr_exit(status);

return 0;

}

注意: 如果有多個子程序退出,而需要等待特定的子程序退出時,可以使用wait的返回值與某個期望的id比較。(三)waitpid函式

#include #include pid_t  waitpid(pid_t   pid,   int   *status,   int

options);

該函式的都是等待特定子程序的退出,如果成功返回退出程序的id,如果出錯返回-1。(1)呼叫waitpid函式

(2)獲得終止狀態與wait相同

(四)exec函式

#include extern char **environ;

int execl(const char *path, const char *arg, ...);

int execv(const char *path, char *const argv);

int execle(const char *path, const char *arg,

..., char * const envp);

int execlp(const char *file, const char *arg,

...);

int execvp(const char *file, char *const argv);

int execvpe(const char *file, char *const argv,

char *const envp);

(1)當程序呼叫exec函式時,exec並不建立新的程序,前後id不改變,該程序執行的程式被完全替代為exec新程式,新的程式從main函式開始執行,exec只是用磁碟上的乙個新的程式替換了當前程序的證正文段,資料段,堆段和棧段。(2)函式區別:

例如:

#include #include #include char * env_init = ;

int main()

else if( pid == 0 )

}if( waitpid( pid,null,0) != pid )

if( (pid = fork()) == -1 )

else if( pid == 0 )

}return 0;

}

(五)典型的程序

(1)孤兒程序

產生原因: 父程序終止,子程序會被init程序收養,此時的子程序就是孤兒程序。

產生過程: 程序終止時,核心逐個檢查所有活動程序,以判斷他是否是正要終止程序的子程序,如果是,則該程序的父程序,id就更改為1,這樣就保證了每個程序的都有乙個父程序。

(2)僵死程序

產生原因:乙個程序已經終止,但是其父程序,尚未對其進行善後處理(獲取終止子程序的有關資訊,釋放他仍占用的資源)的程序被稱為僵死程序。父程序沒有等待取得子程序的終止狀態。

避免方法: 核心為每個終止子程序儲存了一定量的資訊,所以當終止程序的父程序呼叫wait或waitpid時,可以得到這些資訊,這些資訊包括程序id,程序的終止狀態,以及程序使用的cpu時間總量。

注意:如果乙個孤兒程序終止時會成為僵死程序麼?:其實是不會的,原因為init程序中的子程序終止時,init會呼叫乙個wait函式取得其終止狀態,這樣可以防止產生僵死程序。

例如:

#include #include #include int main()

else if( pid == 0 )

else

return 0;

}

Linux程序控制程式設計之fork wait

本文將記錄我在學習fork和wait waitpid 這兩個函式的過程。1.fork 在linux中,建立乙個新程序常用fork函式,它非常特別,執行一次,居然返回兩個值,這與一般的函式是大大的不一樣的,這點引起了我高度的注意。prototype pid t fork void return 0 子...

LINUX環境程式設計之程序控制(上)

每個程序都有乙個非負整型表示的唯一程序id。雖然該id是唯一的,但是程序id是可復用的。當乙個程序終止後,其程序id就成為復用的候選者。系統中有一些專用程序,但是具體細節隨實現而不同。id為0的程序通常是排程程序,常常被稱為交換程序。該程序是核心的一部分,它並不執行任何磁碟上的程式,因此也被成為系統...

linux程序控制程式設計

一 程序與程式 程式是放到磁碟的可執行檔案 程序是指程式執行的例項 程序是動態的,程式是靜態的 程式是有序 的集合 程序是程式的執行。通常程序不可在計算機之間遷移 而程式通常對應著檔案 靜態和可以複製。程序是暫時的,程式使長久的 程序是乙個狀態變化的過程,程式可長久儲存。程序與程式組成不同 程序的組...