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