[UNIX C学习笔记] 1.6 程序和进程 【创建子进程】

来源:互联网 发布:网络剧《余罪》解冰 编辑:程序博客网 时间:2024/06/16 22:47

预备知识:


1、pid_t fork(void);  // 创建一个子进程,若返回0说明当前是 子进程;若返回大于0的数说明当前是父进程,并且返回值为子进程的pid;若返回小于0的书,说明创建子进程失败。


2、exec函数,有六种变体。本例子中只使用其中一个 int execlp(const char *file, const char *arg, ...);   //exec家族的函数 将一个新的进程镜像 来替换当前的镜像。只有这个替换失败函数才会返回。所以,只要调用成功 那么这个函数以下的代码毫无用处,改程序会完全变成另外一个程序。




下面是 一个例子,我们将执行【./a.out 3 】来实现我们的目的,创建一个子进程 执行【./a.out  1  . 】列出当前路径下的 所有文件。



#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <dirent.h>#include <unistd.h>#include <sys/wait.h>#define BUFERSIZE 1024int global_value = 1234;int main(int argc, char* argv[]){    int i = 0;    if(argc>1)        i = atoi(argv[1]);    printf("\n%s's pid = %d\n\n", argv[0], getpid());    //i=1;    if(i==1)    {//list dir        DIR * dp;        struct dirent * dirp;        if(argc < 3)        {            printf("usage : ls dir_name\n");            exit(1);        }        if((dp=opendir(argv[2]))==NULL)        {            printf("can't open %s\n", argv[1]);            exit(1);        }        while((dirp=readdir(dp))!=NULL)            printf("%s\n", dirp->d_name);        closedir(dp);    }    if(i==2)    {//stdin -> stdout        int iCount;        char sBuf[BUFERSIZE];        while((iCount=read(STDIN_FILENO, sBuf, BUFERSIZE))>0)            if(write(STDOUT_FILENO, sBuf, iCount)!=iCount)            {                printf("write eror\n");                exit(1);            }        if(iCount<0)            printf("read error\n");    }    if(i==3)    {//fork a child process        pid_t pid;        int status;        if((pid=fork()) < 0)        {//Failed            printf("fork error~!\n");            exit(1);        }        else if(pid==0)        {//Child            printf("global_value=%d;\tPararent pid = %d;\tChild pid = %d\n", global_value, pid, getpid());            execlp("a.out", "a.out", "1", ".");            printf("Execute a.out ERROR\n");            exit(127);        }        printf("Child's pid = %d\n", pid);        waitpid(pid, &status, 0);    }            return 0;}




下面是执行结结果:
----------------------------------------------------------------------------------------------------------
[/home/maomao/Study/UNIX_C/chap_1]./a.out 3




./a.out's pid = 7411




global_value=1234;      Pararent pid = 0;       Child pid = 7412




a.out's pid = 7412




main.c
a.out
..
Makefile
main.o
.
Makefile1
Child's pid = 7412
----------------------------------------------------------------------------------------------------------


我们会发现 一些现象:


1、execlp函数 调用的新的进程 获取到的 PID  、调用execlp函数之前获取到的PID、以及 父进程 获取到 子进程的PID是一样的。


2、子进程 可以使用父进程的全局变量,这个等后面开始全面讲 进程的时候大家便知 为何。【这是可以视为一种 父子进程 通信的方式】。