fork创建子进程,返回2次是咋回事?

本文详细解析了Linux系统中fork函数的工作原理,解释了为何fork会返回两次,以及子进程如何从fork返回后开始执行。通过分析内核代码,揭示了子进程从ret_from_fork函数开始执行,并且其返回值为0的原因。通过对fork的深入探讨,有助于理解进程创建的本质。
摘要由CSDN通过智能技术生成

在linux系统中,要创建新进程,最常用的方法是调用fork来创建子进程。

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
 
int main(int argc,char *argv[]){
    pid_t pid=fork();
------------------------后面的代码,父子进程都会执行---------------------------------------
    if ( pid < 0 ) {
        fprintf(stderr,"错误!");
    } else if( pid == 0 ) {
        printf("子进程空间");
        exit(0);
    } else {
        printf("父进程空间,子进程pid为%d",pid);
    }
    // 可以使用wait或waitpid函数等待子进程的结束并获取结束状态
    exit(0);
}

上面的代码就是fork的典型用法:创建了一个子进程

在父进程调用完fork函数返回的时候,判断pid的值是一个大于0的值,这个值就是子进程的pid。

子进程开始执行的地方也是fork函数返回的时候,区别就在于子进程返回的pid是0

这里就有一些疑问了,为什么fork函数会返回2次?为什么返回值不一样?为什么子进程可以直接从fork函数之后执行?子进程到底从什么地方开始执行的?

要解开这些疑问,就一定要去看fork在linux内核里面的实现了。

首先第一点,fork函数为什么会返回2次?这描述其实不准确,函数调用返回只会一次。这里是一个进程变成 了两个进程,每个进程都会从fork函数返回,所以是两个进程(父子进程)都从fork返回了。

所以子进程开始执行的地方就是fork返回 的时候。子进程执行的第一句到底 是什么呢?

我们先 来看看子进程到底 是怎么创建出来的。

fork在内核里面的实现是在kernel/fork.c

用户空间的fork函数没有任何参数的时候,通过系统调用进入内核后:

_do_fork(SIGCHLD, 0, 0, NULL, NULL, 0);

参数非常简单,这里也不进行介绍了,查询相关手册就能知道 了。

_dor_fork函数来完成子进程的创建,

_do_fork -> copy_process -> copy_thread_tls -> copy_thread

copy_thread函数做了子进程的寄存器准备工作。

进程的寄存器信息是存放在task_struct->thread_info.reg

copy_thread中先获取到子进程的task_struct->thread_info.reg,然后进程填充:

int copy_thread(unsigned long clone_flags, unsigned long stack_start,
		unsigned long stk_sz, struct task_struct *p)
{
	struct pt_regs *childregs = task_pt_regs(p);
....
    childregs->regs[0] = 0;
....
	p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
	p->thread.cpu_context.sp = (unsigned long)childregs;
}

这里对寄存器做了几个操作,首先会吧reg0写为0.这个寄存器是函数返回值存放的寄存器。所以子进程返回的时候,fork函数返回值就是0

pc指针就是函数即将执行 的代码,这里指向ret_from_fork,也就是子进程开始执行的第一个函数。这个函数就是fork的返回函数。

这样我们就明确了fork子进程是从哪开始执行了,以及为什么子进程fork的返回值是0

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值