Linux上进程fork和vfork

1.简介

  正在执行的一个程序或者命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用
一定的系统资源。
linux上进程有5中状态:

1.运行(正在运行或在运行队列中等待)
2.中断(休眠中,在等待某个条件的形成或接受到信号)
3.不可中断(收到信号不唤醒和不可运行,进程必须等待直到有中断发生)
4.僵死状态(进程已经终止,但进程描述符存在,直到父进程调用wait系统调用后释放)
5.停止(进程收到SIGSTOP,SIGSTP,SIGTIN,SIGTOU信号后停止运行)

查看系统当前进程

ps aux(查看当前时间点进程信息)
ps aux | grep xx (查找xx使用的进程)

可以看进程所属用户,进程pid号

2.fork创建进程

fork创建进程是较常见的方法,参考代码:

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

int main(int argc , char ** argv)
{
    pid_t pid;
    int value = 0;
    printf("-------file name : %s ----\r\n",__FILE__);
    pid = fork();

    if(pid > 0)
    {
        while(1){
            value++;
            printf("This is father: %d \r\n",getpid());
            printf("father : %d\r\n",value);
            sleep(3);
        }
    } else if(pid ==0 )
    {
        while(1){
            printf("This is son: %d \r\n",getpid());
            printf("son : %d\r\n",value);
            sleep(3);
        }
    }
    return 0;
}

运行后,可以看到 从上面fork来看,fork一次调用2次返回,在父进程中,对value进程++,并且打印父进程pid。 子进程中打印value,并不受父进程影响,可见fork是父子进程上下文独立了,子进程从父进程中
拷贝了一份(备注:fork其实不是在调用时就将整个进程空间拷贝一份,而是在操作写进程时,才拷贝的,这
是考虑效率问题的
)。

3.vfork

  直接上代码测试,将上述fork直接改成vfork函数 上述vfork中,在vfork创建好后,子进程先进行,在子进程不退出,父进程根本得不到执行权。
我们修改一下,将子进程调度后exit,保证父进程可以运行,这时才能看到父进程被调度。 备注:此处vfork里面使用了value没有使用volatile修饰,存在实际打印结果与预期不符,可以查看
volatile的使用。

4.总结

  fork出进程后,父子进程被调度,空间相互独立,vfork先调度子进程,只有子进程结束或退出,
才开始父进程,vfork是直接使用父进程空间,不进行写时拷贝。