Linux網絡編程 fork() 和 exec() 函數實例分析



Linux進程在內存裏有三部分數據:代碼段,堆棧段,數據段。相應的 CPU都有上述三種寄存器,以方便操作系統運行,這三部分也是構成一個完整執行序列的必要部分:

代碼段-存放程序代碼的數據

堆棧段-存儲子程序返回地址、子程序參數以及程序局部變量

數據段-存放程序全局變量,常數以及動態數據分配的數據空間

 

Linux環境下,有兩個基本的操作用於創建和修改進程,函數fork()創建一個新的進程,是當前進程的一個拷貝,函數族 exec()用來啓動另外的進程以取代當前運行的進程,下面通過幾個程序來理解 fork()exec()函數的使用方法。

 

程序 fork_test.cpp展示了fork()函數的經典之處,即調用一次,返回兩次,該函數執行有三種類型的返回值:在其創建的子進程中爲0(子進程僅有一個父進程,可通過函數 getppid()獲取其父進程pid),在父進程中爲子進程的ID(因爲一個父進程可能有很多子進程,在父進程中返回子進程ID號便於其跟蹤所有子進程),出錯則返回-1對於出錯的情況即進程終止運行。

#include <unistd.h>
#include <iostream>
using namespace std;

int main(int argc, char **argv)
{
        pid_t fpid;

        fpid = fork();

        if(fpid < 0) cout<<"Fork Error!"<<endl;
        else if(fpid == 0)
        {
                cout<<"The child pid is "<<getpid()<<endl;
        //      cout<<"The Parent pid is "<<getppid()<<endl; // 可獲取其父進程pid
        }
        else
        {
                cout<<"The parent pid is "<<getpid()<<endl;
                //cout<<"the child pid is "<<fpid<<endl; //跟蹤子進程ID,返回爲 Child pid
        }

        return 0;
}

結果:

The parent pid is 3016

The child pid is 3017


程序 exec_test.cpp展示了一個進程想要執行另一個程序,用其派生出的子進程通過exec()函數調用新的程序,然後新的程序將取代當前進程,稱調用exec的進程爲調用進程,一般爲子進程。

注: perror函數爲將上一個函數發生錯誤的原因輸出到標準錯誤(stderr)中,需包含頭文件<stdio>

          wait()函數實現停止當前進程執行,直到被喚醒或者子進程執行結束,頭文件:<sys/wait.h>,其中返回值爲子進程pid

            pid_t wait(int *status);

#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

using namespace std;
#define SUB_ARG_LEN 20


int main(int argc,char **argv)
{
        pid_t fpid,cpid;
        int status;
        char command[SUB_ARG_LEN] = "ls";
        char sub_arg[SUB_ARG_LEN] = "-l";

        fpid = fork();
        if(fpid == 0){
                cout<<"This is Child Process, pid is "<<getpid()<<endl;
                execlp(command,sub_arg,NULL);
                perror(command);
                exit(1);
                //exit(errno);
        }else{
                cout<<"Parent Process is waiting for Child Process running..."<<endl;
                cpid = wait(&status);
                cout<<"This is Parent Process, pid is "<<getpid()<<'\t'<<" child pid is "<<cpid<<endl;
        }
        return 0;
}

結果:

Parent Process is waiting for Child Process running...
This is Child Process, pid is 3028

a.out       exec_test.cpp  intro
byteorder_convert_fun1.cpp  fork_test.cpp  strtoaddr_fun1.cpp

This is Parent Process, pid is 3027  child pid is 3028

參考資料:

UNIX網絡編程卷1:套接字聯網API(第三版)

http://www.oschina.net/question/234345_43605 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章