系统调用fork()用于创建一个新进程。我们可以通过下面的代码来理解,最好是能自己敲一遍运行验证。

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

int main(int args, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < ){
fprintf(stderr,"fork failed\n");
exit();
}else if (rc == ){
printf("hello, I am child (pid:%d)\n", (int) getpid());
}else{
printf("hello, I am parent of %d (pid:%d)\n",rc,(int) getpid());
}
return ;
}

执行结果:

hello world (pid:)
hello, I am parent of (pid:)
hello, I am child (pid:)

整段代码我们可以理解成三大步:

第一步:打印"hello world";

第二步:fork()一个新的进程;

第三步:判断rc的返回值并打印对应的信息;

1)当rc<0时,表示fork一个新进程失败;

2)当rc=0时,表示fork进入的是子进程;

3)当rc等于其他值时,表示fork进程成功,并将子进程的值赋值给rc。

从下面这张图可以很清晰的看到,父进程执行的步骤是123,子进程执行的步骤是23。其中父进程和子进程执行第三步的时候是没有先后顺序的,由CPU调度程序(scheduler)决定在某个哪个进程被执行。也就是上面的结果,后面两行每次打印的顺序结果可能是不一样的。

这里需要特别注意的是:

1、子进程不会从main()函数开始执行,而是直接从fork()系统调用返回,就好像是他自己调用了fork。

2、子进程并不是完全拷贝了父进程。虽然它拥有自己的地址空间(拥有自己的私有内存)、寄存器、程序计数器等,但是它从fork()返回的值是不一样的。父进程获得的返回值是新创建子进程的PID,而子进程获得的返回值是0。

fork()系统调用的理解的更多相关文章

  1. 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

    一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...

  2. fork系统调用(转载)

    (1) fork系统调用说明 fork系统调用用于从已存在进程中创建一个新进程,新进程称为子进程,而原进程称为父进程.fork调用一次,返回两次,这两个返回分别带回它们各自的返回值,其中在父进程中的返 ...

  3. 一个fork()系统调用的问题

    转载:http://coolshell.cn/articles/7965.html 题目:请问下面的程序一共输出多少个“-”? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  4. 以python代码解释fork系统调用

    import os print('Process (%s) start...' % os.getpid()) # Only works on Unix/Linux/Mac: pid = os.fork ...

  5. fork 系统调用

    对自己知识储备的感觉就是过于肤浅,很多东西知其名后就不了了之 此系列博客将记录进程分析的学习过程,希望能够多些深度 提到进程,最容易的想到就是fork系统调用,比较好和快速的找到的fork的相关信息就 ...

  6. fork系统调用方式成为负担,需要淘汰

    微软研究人员发表论文称用于创建进程的 fork 系统调用方式已经很落后,并且对操作系统的研究与发展产生了极大的负面影响,需要淘汰,作者同时提出了替代方案.相信每位开发者都对操作系统中的 fork () ...

  7. 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程

    GDB的那些奇淫技巧 evilpan 收录于 Security  2020-09-13  约 5433 字   预计阅读 11 分钟  709 次阅读  gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...

  8. glibc中fork系统调用传参

    因为想跟踪下在新建进程时,如何处理新建进程的vruntime,所以跟踪了下fork. 以glic-2.17中ARM为例(unicore架构的没找到),实际上通过寄存器向系统调用传递的参数为: r7: ...

  9. 对linux中source,fork,exec的理解以及case的 使用

    fork   使用 fork 方式运行 script 时, 就是让 shell(parent process) 产生一个 child process 去执行该 script, 当 child proc ...

随机推荐

  1. C++ 人脸识别系统的浅理解

    机器学习 机器学习的目的是把数据转换成信息. 机器学习通过从数据里提取规则或模式来把数据转成信息. 人脸识别 人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸. 每个节点的正确识别率很高,但正确 ...

  2. sql 语句系列(多表之链)[八百章之第三章]

    新增连接查询而不影响其他连接查询 请看图: 这种情况我们一般会使用左连接的方式. select e.ENAME,d.LOC,eb.RECEIVED from emp e join dept d on( ...

  3. 150多个Flutter组件详细介绍送给你

    迷茫是什么,迷茫就是大事干不了,小事不想干,能力配不上欲望,才华配不上梦想. 150+Flutter组件详细介绍地址:http://laomengit.com/ 前言 我在Flutter未正式发布之前 ...

  4. docker系列详解<二>之常用命令

    此篇我们以从docker运行一个tomcat为例,进行一下操作: 拉取镜像 查看镜像 创建容器 查看运行状态 进入退出容器 停止容器 重启容器 删除容器 删除镜像 1.拉取tomcat镜像: 1).查 ...

  5. 信息收集工具-dimtry

    GitHub地址: kali下也是自带的: -s以及-e 参数需要用到Google搜索 1.获取whois主机ip信息 2.扫描端口,根据banner信息判断服务

  6. 动态规划-Cherry Pickup

    2020-02-03 17:46:04 问题描述: 问题求解: 非常好的题目,和two thumb其实非常类似,但是还是有个一点区别,就是本题要求最后要到达(n - 1, n - 1),只有到达了(n ...

  7. 使用SparkSQL编写wordCount的词频统计

    # 使用SparkSQL编写wordCount的词频统计 ## word.txt```hello hello scala sparkjava sql html java hellojack jack ...

  8. java实现小功能

    // 自写逻辑,遍历所有匹配的子字符串坐标 private static void forMatchIdx(String str1, String str2) { char[] arr1 = str1 ...

  9. Mock测试,结合Fiddler轻松搞定不同场景

    在平时测试过程中,总会遇到一些比较难构造的场景.比如不同平台间的同步,异常场景的构造.遇到难构造的场景时,就可以引用Mock来进行单元测试.简言之:mock测试就是在测试过程中,对于某些不容易构造或者 ...

  10. ReentrantLock源码解析——虽众但写

    在看这篇文章时,笔者默认你已经看过AQS或者已经初步的了解AQS的内部过程.   先简单介绍一下ReentantLock,跟synchronized相同,是可重入的重量级锁.但是其用法则相当不同,首先 ...