1、init进程
每个进程都会分配一个唯一的数字编号,我们称之为进程标识符或者PID,它通常是一个取值范围从2到32768的正整数。数字1是为特殊进程init保留的。linux系统启动时,它将运行一个名为init的进程,该进程是系统运行的第一个进程,它是其他所有进程的祖先进程。
2、替换进程映像
The exec family of functions replaces the current process image with a new process image.

1int execl(const char *path, const char *arg0, ...,(char *)0); 
(2int execlp(const char *file, const char *arg, ...,(char *)0); 
(3int execle(const char *path, const char *arg , ...(char *)0, char * const envp[]); 
(4int execv(const char *path, char *const argv[]); 
(5int execvp(const char *file, char *const argv[]); 

它们只是参数的类型不同而已
execl中的l表示list,即它的参数是列表形式的
execv中的v表示vector,即它的参数是数组形式的

//unistd的意思是Unix Standard的意思
//文件temp.c
#include<unistd.h>
#include<stdio.h>

int main(void)
{
    printf("running ps with execlp\n");
    execlp("ps", "ps", "ax", 0);
    printf("done\n");

    return 0;
}

运行这个程序,我们会看到先输出running ps with execlp,然后输出ps的输出信息,最后并没有输出done
并且也没有出现temp进程的信息,因为execlp("ps", "ps", "ax", 0);用ps进程替换了temp进程。

再看一些其他的例子:

#include<unistd.h>

// example of a argument list, note that we need a program name for argv[0]
char * const ps_argv[]={"ps", "ax", 0};

execl("/bin/ps", "ps", "ax", 0);
execlp("ps", "ps", "ax", 0);       // assume /bin is in PATH
execv("/bin/ps", ps_argv);
execvp("ps", ps_argv);

3、复制进程映像
fork创建一个新进程,这个系统调用复制当前进程,在进程表中创建一个新的表项,新的表项中的许多属性与当前进程是相同的。

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main(void)
{
    pid_t pid;
    char *message;
    int n;

    printf("fork program starts\n");
    pid = fork();
    switch(pid)
    {
    case -1:
        printf("error\n");
        return -1;
    case 0:
        message = "this is child";
        n=5;
        break;
    default:
        message = "this is parent";
        n=3;
        break;
    }

    for(; n>0;n--)
    {
        puts(message);
        sleep(1);
    }

    return 0;
}


输出
zzj@zzj-PC  ~/tmp
$ ./tmp
fork program starts
this is parent
this is child
this is parent
this is child
this is parent
this is child
this is child

zzj@zzj-PC  ~/tmp
$ this is child

4、等待一个进程

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

int main(void)
{
    pid_t pid;
    char *message;
    int n;
    int exit_code;

    printf("fork program starts\n");
    pid = fork();
    switch(pid)
    {
    case -1:
        printf("error\n");
        return -1;
    case 0:
        message = "this is child";
        n=5;
        exit_code = 100;
        break;
    default:
        message = "this is parent";
        n=3;
        exit_code = 0;
        break;
    }

    for(; n>0;n--)
    {
        puts(message);
        sleep(1);
    }

    if(pid != 0)
    {
        int stat_val;
        pid_t child_pid;
        child_pid = wait(&stat_val);

        printf("child has finished :PID=%d\n", child_pid);
        if(WIFEXITED(stat_val))
        {
            printf("child exited with code %d\n",WEXITSTATUS(stat_val));
        }
        else
        {
            printf("child terminated abnormally\n");
        }
    }

    exit(exit_code);

    return 0;
}

父进程用wait系统调用将自己的执行挂起,直到子进程的状态信息出现为止