1. 程式人生 > >Linux高階程式設計基礎——程序之多個子程序

Linux高階程式設計基礎——程序之多個子程序

程序之多個子程序

  1. 建立子程序一,在子程序中遞迴列印/home目錄中的內容(可以用exec系列函式呼叫第一次實驗中的程式碼完成此功能);
  2. 子程序退出的時候呼叫cpexit()函式,在cpexit()函式中完成以下功能:
    列印字串“Child process exited!”列印子程序識別符號,列印父程序識別符號。
  3. 建立子程序二, 列印子程序執行環境中環境變數“USER”的值,通過exec系列中的某個函式設定子程序”USER”環境變數值為“zhangsan”,並且讓該子程序同時完成以下命令:“ls –li /home”.*/
#include <stdio.h>
#include <stdlib.h>                             //編譯這個檔案時,先 要把遍歷目錄的程式 編譯
#include <string.h>                            //例如 :gcc bianli.c -o text   (這個是編譯遍歷目錄的程式 這個text一定要和程式碼中說的那個“./text”相同)
#include <sys/types.h>                       //           gcc jinchengbianli.c -o test  (這個是編譯這個程式)
#include <unistd.h>                            //                 ./test         (執行這個實驗)

void cpexit ()  //登記函式
 {
   printf ("child process exited! \n");
   printf ("child's pid : %d \n father's pid : %d \n",getpid(),getppid());  //"getpid()"列印子程序id ,getppid()列印父程序id 
 }

int main()
{
int pid1,pid2;
pid1 = fork();  //建立子程序 1
 if (pid1 == 0)   //如果pid1為 0 ,那就是子程序                            
   {                 //這個peng,需要改動,開啟你的終端在@ubuntu或者@redhat 前面寫的什麼,把這個peng就該成什麼                                            
     execl("/home/peng/text","./text",NULL);  //作用是遞迴列印/home目錄中的內容,實現方式是:需要先編譯前面寫的那個遍歷目錄的程式《gcc bianli.c -o text》 “bianli.c”這是我遍歷目錄的程式名字,你跟據你的那個程式名字來編譯,“text” 這個是可執行檔案,這個要和“./text”保持一致(意思就是如果gcc * * * x,那麼就是“./x”) "./text"這是直接找到編譯完成之後的檔案(text)然後執行這個檔案。
     printf ("child's pid : %d \n",getpid());
     atexit (cpexit);  //呼叫登記函式,“cpexit”這個就是登記的函式
     exit (0); //退出子程序 1
   }
pid2 = fork();   //建立子程序 2

 if (pid2 == 0)  //判斷是否為子程序
   {
     char *argv[] = {"ls","-li","/home",NULL}; //這個陣列儲存的命令是,檢視home下的內容
     char *argc[] = {"USER = zhangsan",NULL};  //這個陣列儲存的命令是:給USER這個環境變數賦值為 zhangsan,
     printf ("USER這個環境變數的值為:%s \n",getenv ("USER"));   //列印USER這個環境變數的值
     execve ("/bin/ls",argv,argc);   //“/bin”是一個函式庫,ls 命令在這個庫函式中存放,這行程式碼實現的就是argv這個數組裡面的命令,
     printf ("%s \n",getenv ("USER"));  //雖然這次輸出環境變數的值,但是並沒有輸出,因為在execve裡面只是執行了第一個的/bin/ls操作,並且在裡面出不來了
     exit (0);//退出子程序 2
   }
return 0;
}

  1. 登記函式裡面打印出來的子程序id和在子程序中打印出來的是否一樣? 是一樣的
  2. 登記函式什麼時候呼叫的 ?
    在子程序結束前呼叫的 在子程序結束前呼叫的
  3. execve中第二個陣列為什麼沒有執行?
    exec函式族的函式執行成功後不會返回,因為呼叫程序的實體,包括程式碼段,資料段和堆疊等都已經被新的內容取代,exec函式族的函式執行成功後不會返回,因為呼叫程序的實體,包括程式碼段,資料段和堆疊等都已經被新的內容取代,