exec函数介绍(整理)(附带:操作系统实验一:进程控制实验 代码)
(1)exec函數說明
fork函數是用于創建一個子進程,該子進程幾乎是父進程的副本,而有時我們希望子進程去執行另外的程序,exec函數族就提供了一個在進程中啟動另一個程序執行的方法。它可以根據指定的文件名或目錄名找到可執行文件,并用它來取代原調用進程的數據段、代碼段和堆棧段,在執行完之后,原調用進程的內容除了進程號外,其他全部被新程序的內容替換了。另外,這里的可執行文件既可以是二進制文件,也可以是Linux下任何可執行腳本文件。
(2)在Linux中使用exec函數族主要有以下兩種情況
當進程認為自己不能再為系統和用戶做出任何貢獻時,就可以調用任何exec 函數族讓自己重生。
如果一個進程想執行另一個程序,那么它就可以調用fork函數新建一個進程,然后調用任何一個exec函數使子進程重生。
————————————————
版權聲明:上面這段來自CSDN博主「guoping16」的原創文章,遵循 CC 4.0 BY-SA 版權協議,
原文鏈接:https://blog.csdn.net/guoping16/article/details/6583383
exec和fock簡述
exec系統調用從指定程序重新初始化進程,雖然進程還在,但程序已經改變了。
fock系統調用僅通過復制指令、用戶數據和系統數據段來創建從現存進程克隆的新進程,該新進程不是從程序初始化得來的,所以舊進程和新進程執行同樣的指令。
除啟動UNIX內核本身外,exec是程序在UNIX上獲得執行的唯一方法,不僅shell使用exec執行程序,而且shell和其祖先shell也會被exec調用。fock是創建新進程的唯一方式。
————————————————
版權聲明:上面這段來自CSDN博主「方同學Max」的原創文章,
原文鏈接:https://blog.csdn.net/csu_max/article/details/38086223
一個進程主要包括以下幾個方面的內容:
(1)一個可以執行的程序
(2) 與進程相關聯的全部數據(包括變量,內存,緩沖區)
(3)程序上下文(程序計數器PC,保存程序執行的位置)
exec是一個函數簇,由6個函數組成,分別是以excl和execv打頭的。
執行exec系統調用,一般都是這樣,用fork()函數新建立一個進程,然后讓進程去執行exec調用。我們知道,在fork()建立新進程之 后,父進各與子進程共享代碼段,但數據空間是分開的,但父進程會把自己數據空間的內容copy到子進程中去,還有上下文也會copy到子進程中去。而為了 提高效率,采用一種寫時copy的策略,即創建子進程的時候,并不copy父進程的地址空間,父子進程擁有共同的地址空間,只有當子進程需要寫入數據時 (如向緩沖區寫入數據),這時候會復制地址空間,復制緩沖區到子進程中去。從而父子進程擁有獨立的地址空間。而對于fork()之后執行exec后,這種 策略能夠很好的提高效率,如果一開始就copy,那么exec之后,子進程的數據會被放棄,被新的進程所代替。
總之,如果你用exec調用,首先應該fork一個新的進程,然后exec
————————————————
版權聲明:上面這段來自CSDN博主「smart_yujin」的原創文章,
原文鏈接:https://blog.csdn.net/smart_yujin/article/details/10515247
說了很多,但自己用的時候還是沒有徹底理解execve函數的運用,忘記了它的性質:系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。因此,可以這樣認為,exec系統調用并沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。
來看一個例子吧:
示例代碼:
要求:
編寫一個多進程并發執行程序。父進 程首先創建一個執行ls命令的子進程然后再創建一個執行ps命令的子進程,并控制 ps 命令總在 ls 命令之前執行。
頭文件:
#include <sys/types.h> #include <wait.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> //進程自定義的鍵盤中斷信號處理函數 typedef void (*sighandler_t) (int); void sigcat() {printf("%d Process continue\n",getpid()); }linux系統中執行上面的代碼后,發現子進程2中用execve執行ps命令后,并沒有發送信號給子進程1,既沒有提示信號發送成功,也沒有提示信號未發送成功,而是子進程2中execve下面的代碼好像直接給忽略了,沒有執行。所以,子進程1 pause()之后,需要我們手動發送信號,按下Crtl+C去喚醒Child 1.
關于信號,參考:https://www.cnblogs.com/nufangrensheng/p/3514157.html
信號:SIGINT 由Interrupt Key產生,通常是CTRL+C或者DELETE。
正確的代碼:應該是child 2中execve之后不要再有任何代碼(這時它們屬于原進程的代碼),即使有,也被執行execve時載入的進程的新代碼替代掉了,不會執行。
正確方法應該是,父進程等待子進程2執行完畢,并且在父進程中把子進程1喚醒,子進程1繼續執行完畢。
如下:(頭文件仍舊不變)
總結
以上是生活随笔為你收集整理的exec函数介绍(整理)(附带:操作系统实验一:进程控制实验 代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: glReadPixels的用法和说明
- 下一篇: Linux的目录结构和头文件相关;哪里找