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