日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

exec函数介绍(整理)(附带:操作系统实验一:进程控制实验 代码)

發布時間:2025/6/17 windows 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

  • 系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。因此,可以這樣認為,exec系統調用并沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。
  • 一個進程主要包括以下幾個方面的內容:

    (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 命令之前執行。

    /* * Function : 多進程的并發執行 */#include "myTest1.h" int main(int argc, char *argv[]){int i;int pid1, pid2; //存放子進程號 int status1, status2; //存放子進程返回狀態第二部分 操作系統算法實驗 char *args1[] = { "/bin/ls","-a",NULL }; //子進程1要缺省執行的命令 char *args2[] = { "/bin/ps","-l",NULL }; //子進程2要缺省執行的命令 signal(SIGINT, (sighandler_t)sigcat); //注冊一個本進程處理鍵盤中斷的函數 pid1 = fork(); //建立子進程 1if (pid1 < 0) // 建立子進程失敗? {printf("Create Process1 fail!\n");exit(EXIT_FAILURE);}if (pid1 == 0) // 子進程執行代碼段 {//報告父子進程進程號 printf("I am Child1 process %d\nMy father is %d\n", getpid(), getppid());pause(); //暫停,等待鍵盤中斷信號喚醒 //子進程1被鍵盤中斷信號喚醒繼續執行 printf("%d child1 will Running: \n", getpid()); // //裝入并執行新的程序 status1 = execve(args1[0], args1, NULL);}else //父進程執行代碼段 {printf("\nI am Parent process %d\n", getpid()); //報告父進程進程號 pid2 = fork();if(pid2<0){printf("Create Process2 fail!\n");exit(EXIT_FAILURE);}if (pid2 == 0) // 子進程執行代碼段 {//報告父子進程進程號 printf("I am Child2 process %d\nMy father is %d\n", getpid(), getppid());//裝入并執行新的程序 status2 = execve(args2[0], args2, NULL);//子進程2執行完了,喚醒子進程1/* 系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。因此,可以這樣認為,exec系統調用并沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。 *///所以,下面的部分并沒有執行,所以需要手動按Ctrl+C喚醒,而不是自動發信號喚醒 if (kill(pid1, SIGINT) == 0)printf("%d Wakeup its brother %d.\n", getpid(), pid1);else printf("%d send signal failed.\n", getpid());}}waitpid(pid2, &status2, 0); //等待子進程結束printf("\nMy child2 exit! status = %d\n\n", status2);waitpid(pid1, &status1, 0); //等待子進程結束printf("\nMy child1 exit! status = %d\n\n", status1);return EXIT_SUCCESS;}

    頭文件:

    #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繼續執行完畢。
    如下:(頭文件仍舊不變)

    /* * Function : 多進程的并發執行 */#include "myTest1.h" int main(int argc, char *argv[]){int i;int pid1, pid2; //存放子進程號 int status1, status2; //存放子進程返回狀態第二部分 操作系統算法實驗 char *args1[] = { "/bin/ls","-a",NULL }; //子進程1要缺省執行的命令 char *args2[] = { "/bin/ps","-l",NULL }; //子進程2要缺省執行的命令 signal(SIGINT, (sighandler_t)sigcat); //注冊一個本進程處理鍵盤中斷的函數 pid1 = fork(); //建立子進程 1if (pid1 < 0) // 建立子進程失敗? {printf("Create Process1 fail!\n");exit(EXIT_FAILURE);}if (pid1 == 0) // 子進程執行代碼段 {//報告父子進程進程號 printf("I am Child1 process %d\nMy father is %d\n", getpid(), getppid());pause(); //暫停,等待鍵盤中斷信號喚醒 //子進程1被鍵盤中斷信號喚醒繼續執行 printf("%d child1 will Running: \n", getpid()); // //裝入并執行新的程序 status1 = execve(args1[0], args1, NULL);}else //父進程執行代碼段 {printf("\nI am Parent process %d\n", getpid()); //報告父進程進程號 pid2 = fork();if(pid2<0){printf("Create Process2 fail!\n");exit(EXIT_FAILURE);}if (pid2 == 0) // 子進程執行代碼段 {//報告父子進程進程號 printf("I am Child2 process %d\nMy father is %d\n", getpid(), getppid());//裝入并執行新的程序 status2 = execve(args2[0], args2, NULL);//子進程2執行完了,喚醒子進程1/* 系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。因此,可以這樣認為,exec系統調用并沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。 *///所以,下面的部分并沒有執行,所以需要手動按Ctrl+C喚醒,而不是自動發信號喚醒 /*if (kill(pid1, SIGINT) == 0)printf("%d Wakeup its brother %d.\n", getpid(), pid1);else printf("%d send signal failed.\n", getpid());*/}}waitpid(pid2, &status2, 0); //等待子進程結束printf("\nMy child2 exit! status = %d\n\n", status2);if (kill(pid1, SIGINT) == 0)printf("%d Wakeup %d.\n", getpid(), pid1);else printf("%d send signal failed.\n", getpid());waitpid(pid1, &status1, 0); //等待子進程結束printf("\nMy child1 exit! status = %d\n\n", status1);return EXIT_SUCCESS;}

    總結

    以上是生活随笔為你收集整理的exec函数介绍(整理)(附带:操作系统实验一:进程控制实验 代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。