面试官:来讲一讲进程

linux 进程如何创建

Linux系统创建进程都是由已存在的进程创建的(除了0号进程),被创建的进程叫做子进程,创建子进程的进程就做父进程。这句话是不是有点熟悉,没错,Linux进程串起来也是一颗树的结构

在Linux中,为了创建一个子进程,父进程用系统调用fork来创建子进程。fork()其实就是把父进程复制了一份(子进程有自己的特性,比如标识、状态、数据空间等;子进程和父进程共同使用程序代码、共用时间片等)。

可以看下面这段代码:



#include<stdio.h>
#include<unistd.h>

int main()
{
    int p_num = 0;
    int c_num = 0;
    int pid = fork();
    if(pid == 0) //返回的pid为0为子进程
    {
        c_num++;
    }
    else
    {
        p_num++; //返回的pid大于0为父进程
    }
    printf("p_num=%d, c_num=%d\n",p_num,c_num);
    printf("pid=%d\n",pid);
    return 0;
}
//运行结果如下所示
p_num=1, c_num=0
pid=36101
p_num=0, c_num=1
pid=0


大家看,代码中调用了fork以后,之后的程序被执行了两遍。子进程和父进程各自的变量互相没有受到干扰。不过子进程和父进程执行的是相同的代码,子进程和父进程资源占用情况如下图所示:


大家可以看出,通过fork后,子进程并没有和父进程独立开,用的是相同的代码。另外还有一个问题时,这个时候子进程的时间片是和父进程一分为二来共享的。这样我创建子进程还有什么意义?为了彻底将父进程和子进程分离开来,就要用到一个系统调用 execv()。

看下面这段代码:



//process.c
#include<stdio.h>
#include<unistd.h>

int main()
{
    int pid = fork();
    if(pid == 0)
    {
        execv("./test.o",NULL);  //test.o是一个经过编译的c语言文件,这里记得要放test.o的绝对路径
    }
    printf("This is parent process\n");
    return 0;
}

//test.c
#include<stdio.h>
int main()
{
    printf("This is child process");
    return 0;
}

//运行结果如下所示
This is parent process
This is child process

通过上面的代码可以看出,从系统调用 execv() 后,子进程直接走自己的代码了,没有像前一段代码一样把后面的代码执行了两次。通过调用 execv(),子进程和父进程就基本分离开了。

 1
 0
 分享
评论图片
评论