007 Linux fork()函数

前言

本文将会以提问的形式展开向你介绍fork函数

文章重点

关于fork函数,本文重点在于解决以下疑问

疑问一:
为什么fork之前的代码只有父进程执行,然而fork之后的代码父子进程都要执行
疑问二:
1、既然fork之后父子进程会执行一样的代码,那么子进程的意义是什么?
2、为什么fork的两个返回值,会给父进程返回子进程的pid,给子进程返回0
疑问三:
1、为什么fork会有两个返回值
2、如何理解同一个变量,会有不同的值
3、fork之后,父子进程谁先运行

引入fork()函数

linux系统是用c语言写的,所以在linux中创建一个进程实际上也要调用c语言的函数也就是用代码创建进程叫做系统调用,fork函数是Linux系统中实现多进程编程的基础,通过fork函数,可以创建一个子进程,然后在子进程中执行不同的任务,从而实现并行计算和多任务处理。

fork解析一

使用man指令查看fork函数信息
在这里插入图片描述

#include<stdio.h>    
#include<unistd.h>    
#include<sys/types.h>    
int main()    
{    
    printf("我是一个进程,pid:%d ppid:%d\n",getpid(),getppid());                                                                                                         
    while(1)    
    {              
        fork();                                                          
        printf("i am a process,pid:%d ppid:%d\n",getpid(),getppid());    
        sleep(1);    
    }       
    return 0;
}   

观察结果
在这里插入图片描述
可以观察到子进程已经被创建出来了(pid为5584)

疑问:为什么fork之前的代码只有父进程执行,然而fork之后的代码父子进程都要执行(观察结果的后两行->父子进程都执行了代码),并且为什么子进程不会从头开始执行父进程的代码?

原因是: 子进程以父进程为模板,把父进程中的大部分属性拷贝给子进程
fork会创建子进程,系统中会多出一个子进程,操作系统以父进程为模板为子进程创建PCB,但是创建的子进程是没有代码和数据的!!目前和父进程共享代码和数据
所以fork之后,父子进程会执行一样的代码,创建出来的子进程并不从头开始执行父进程的代码,而是从fork函数之后的代码开始执行(父进程的大部分属性拷贝给了子进程,包括寄存器的状态->用于记录当前指令的执行位置和保存临时数据)

fork解析二

观察第二第三行分别是父进程和子进程执行的结果
在这里插入图片描述

疑问二:
1、既然fork之后父子进程会执行一样的代码,那么子进程的意义是什么?
2、为什么fork的两个返回值,会给父进程返回子进程的pid,给子进程返回0

引入: fork成功的时候会有两个不同的返回值,给子进程返回0,给父进程返回子进程的pid
为什么要创建子进程呢:我们想让子进程协作父进程完成一些工作,这些工作是单进程解决不了的
可以通过判断fork的返回值,来让父子进程执行不一样的代码,让子进程实现和父进程不一样的功能,比如:我们可以一边玩游戏一边听着音乐,这两个过程就是不同的进程在执行

#include<stdio.h>                                                                                                                                                       
#include<sys/types.h>    
#include<unistd.h>    
int main()    
{    
    printf("我是一个父进程,我的pid是: %d\n",getpid());    
    
    pid_t id = fork();    
    
    if(id==0)//子进程的代码片段    
    {    
        while(1)    
        {    
            printf("我是子进程: pid:%d ppid: %d ret:%d,我在进行下载任务\n",getpid(),getppid(),id);    
            sleep(1);    
        }    
    }    
    else if(id>0)//父进程的代码片段    
    {    
    
        while(1)    
        {    
            printf("我是父进程: pid:%d ppid: %d ret:%d,我在进行播放任务\n",getpid(),getppid(),id);    
        sleep(1);    
        }    
    }
    return 0;
}

pid_t id = fork();
观察结果:fork成功的时候会有两个不同的返回值,给子进程返回0,给父进程返回子进程的pid
在这里插入图片描述

一个父进程可以创建很多个子进程,然而一个子进程只对应一个父进程,所以fork函数会返回子进程的id给父进程,方便父进程管理它的子进程

fork解析三

1、为什么fork会有两个返回值
2、如何理解同一个变量,会有不同的值
3、fork之后,父子进程谁先运行

在这里插入图片描述

1、创建完子进程后,子进程会共享父进程的代码和数据,很明显return也是一句代码,所以父子进程都会执行return语句,fork函数有两个返回值

pid_t id = fork();
打印id地址
在这里插入图片描述
观察到父子进程的返回值id是不一样的,但是地址却是一样的。
怎么可能同一个变量,同一个地址,会有不同的内容(变量id在父进程和子进程中值不同)呢?

2、进程具有独立性,首先表现在进程各自的PCB运行时不会相互影响,很明显,代码本身只是可读的,所以不是影响代码,但是对于数据来说,父子的数据是可能不同的(可能会被修改)
所以系统是怎样做到让数据在各个进程都自己私有一份的,答案是写时拷贝,数据会在需要使用时被写时拷贝到PCB,然而fork返回值赋值给变量时,本质也是写入,返回时也会发生写时拷贝,所以不同的进程执行的代码中的变量id获取的值不同

3、那么fork之后,父子进程谁先运行?
在调度队列中,cpu会选择一个进程去运行它,谁先被调度谁先运行,所以fork之后父子进程谁现在运行是不确定的,这是由各自进程PCB中的调度信息决定的,比如优先级,算法信息等。

小结

今日的分享就到这里啦,后面将会向你带来进程的状态,优先级,进程地址空间等知识,如果本文存在疏漏或错误的地方还请您能够指出!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/146034.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序:页面跳转传参问题

今天后端大兄弟突然拿着一个反编译过来的小程序源码&#xff0c;问能不能改。我心里直道好家伙&#xff0c;WebGIS开发的岗位&#xff0c;前端的活儿真是一个不少。大致看了看有几处是调整页面和接口修改的&#xff0c;源码部分和Vue项目语法十分相像&#xff0c;就临阵磨枪&am…

【java面试题】Integer对象输出结果是?

/** Copyright (c) 2006, 2023, webrx.cn All rights reserved.**/package cn.webrx;/*** <p>Project: wxbili2mp4 - Test* <p>Powered by webrx On 2023-11-14 20:28:46* <p>描述&#xff1a;<p>** author webrx [webrx126.com]* version 1.0* since …

2.3.5 交换机的VRRP技术

实验2.3.5 交换机的VRRP技术 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.交换机的基本配置 六、任务验收七、任务小结 一、任务描述 某公司的网络核心层原来采用一台三层交换机&#xff0c;随着网络应用的日益增多&#xff0c;对网络的可靠性也提出了越来…

生信分析|基因组倍型鉴定

简介 基因组倍型通常指一个生物体细胞中染色体的组合&#xff0c;即染色体数目的倍数。在生物学中&#xff0c;主要有两种类型的基因组倍型&#xff1a;单倍体和多倍体。 「单倍体&#xff08;Haploid&#xff09;&#xff1a;」 单倍体生物体的细胞中只包含每一对同源染色体的…

凸包的学习之路

学习视频选择的是&#xff1a;清华大学邓俊辉教授的《计算几何》课程 关于我为什么学习 凸包&#xff08;Convex Hull&#xff09;&#xff1f; ——在学习过程中遇到了凸包问题&#xff0c;凸包在CV领域的基础性&#xff0c;使我觉得深入了解凸包是必要的。此外&#xff0c;…

交换机基础知识之安全配置

交换机在网络基础设施中扮演着重要角色&#xff0c;它促进了设备之间数据包的流动。正因此&#xff0c;采取适当的安全措施来保护网络免受未经授权的访问和潜在攻击至关重要。本文将全面解读交换机基础安全配置知识&#xff0c;并提供实践方案&#xff0c;以保证安全的网络环境…

【Linux】-再谈动静态库-手把手教你自己制作一个动静态库

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

计算机缺失vcruntime140.dll如何修复?超简单的5个解决方法

在我们日常使用电脑的过程中&#xff0c;可能会遇到各种各样的问题和错误提示。其中&#xff0c;一个比较常见的错误提示就是“vcruntime140.dll丢失”。这个错误通常发生在我们尝试运行某个程序或应用时&#xff0c;系统无法找到或加载所需的vcruntime140.dll文件。 vcruntime…

Ubuntu安装mysql(解决ubuntu Access denied for user ‘root‘@‘localhost‘报错)

1、安装mysql sudo apt-get install mysql-server 上述命令会安装以下包&#xff1a; apparmor mysql-client-5.7 mysql-common mysql-server mysql-server-5.7 mysql-server-core-5.7 因此无需再安装mysql-client等。安装过程会提示设置mysql root用户的密码&#xff0c;设…

Java —— 继承

目录 1. 为什么需要继承 2. 继承概念 3. 继承的语法 4. 父类成员访问 4.1 子类中访问父类的成员变量 1. 子类和父类不存在同名成员变量 2. 子类和父类成员变量同名 4.2 子类中访问父类的成员方法 1. 成员方法名字不同 2. 成员方法名字相同 5. super关键字 6. 子类构…

Istio学习笔记-体验istio

参考Istio 入门(三)&#xff1a;体验 Istio、微服务部署、可观测性 - 痴者工良 - 博客园 (cnblogs.com) 在本章中&#xff0c;我们将会学习到如何部署一套微服务、如何使用 Istio 暴露服务到集群外&#xff0c;并且如何使用可观测性组件监测流量和系统指标。 本章教程示例使用…

【JAVA学习笔记】70 - 反射

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter23/src 反射 一、反射的引出 package com.yinhai.reflection.question;import com.yinhai.Cat;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IO…

全链路自动化测试

背景 从 SOA 架构到现在大行其道的微服务架构&#xff0c;系统越拆越小&#xff0c;整体架构的复杂度也是直线上升&#xff0c;我们一直老生常谈的微服务架构下的技术难点及解决方案也日渐成熟&#xff08;包括典型的数据一致性&#xff0c;系统调用带来的一致性问题&#xff0…

vue day1(主要是指令)

1、引包 或者&#xff1a;cdn网址 2、创建实例&#xff0c;初始化渲染 3、插值表达式 {{}} 表达式&#xff1a;可以被求值的代码 4、响应式数据&#xff1a;数据发生变化&#xff0c;视图自动更新&#xff08;底层是dom操作&#xff09; data中数据会被添加到实例上&#x…

微信自动添加好友

简要描述&#xff1a; 添加微信好友 请求URL&#xff1a; http://域名地址/addUser 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId…

易点易动固定资产管理系统:RFID技术助力快速盘点数万固定资产

在当今的企业管理中&#xff0c;高效和准确的固定资产盘点是至关重要的。传统的资产盘点方法通常耗时且易出错&#xff0c;这在快节奏的商业环境中是企业难以承受的。易点易动固定资产管理系统通过采用射频识别&#xff08;RFID&#xff09;技术&#xff0c;为企业提供了一种革…

竞赛 题目:基于python的验证码识别 - 机器视觉 验证码识别

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于pyt…

【教3妹学编辑-mysql】mybatis查询条件遇到的坑及解决方案

2哥 :3妹&#xff0c;今天怎么下班这么晚啊。 3妹&#xff1a;嗨&#xff0c;别提了&#xff0c;今天线上出bug了&#xff0c; 排查了好久。 2哥&#xff1a;啊&#xff0c;什么问题呀&#xff1f; 3妹&#xff1a;我们内部的一个管理系统报错了&#xff0c; 最近排查下来是myb…

Gempy 实现地理位置3D模型的展示以及导出

1. 首先安装python gempy 包 pip install gempy python 版本 3.10 这个很重要,版本不同可能会报错 2. gdal 可能会报错, 一下地址根据python版本下载,然后移入到python解释器环境中, Script文件中,然后cmd ,pip install 文件名安装即可 Releases cgohlke/geospatial-wheels …

NI和EttusResearchUSRP设备之间的区别

NI和EttusResearchUSRP设备之间的区别 概述 USRP&#xff08;通用软件无线电外设&#xff09;设备是业界领先的商软件定义无线电&#xff08;SDR&#xff09;。全球数以千计的工程师使用USRPSDR来快速设计、原型设计和部署无线系统。它们以两个不同的品牌进行营销和销售&…