【Linux系统化学习】进程的父子关系 | fork 进程

news2025/1/18 11:05:38

=========================================================================

个人主页点击直达:小白不是程序媛

Linux专栏:Linux系统化学习

=========================================================================

目录

前言:

父子进程

父子进程的引入

查看父子进程 

查询进程的动态目录

更改进程的工作目录

fork创建进程

fork的引入

fork的使用

fork的原理

fork如何实现的?

为什么fork之前的代码不执行?

为什么要有两个返回值?


前言:

上篇文章我们谈到了进程,运行在内存的程序、被执行的指令都可以是一个进程;并且对Linux的进程有一定的认识,知道如何使用指令查看进程和第一个系统调用。进程还有很多的奥秘需要我们探索,让我们开始今天的学习吧!


父子进程

父子进程的引入

还是上篇文章的代码和指令,每个进程都PID,在属性列表前面的PPID父进程的ID。

我们对自己写的可执行程序进行多次的运行和终止,会发现每次的进程ID都会变,而父进程ID始终不变。 

 经过查询我们可以知道这个父进程就是我们的命令行解释器(bash)

总结:

  • 启动进程本质就是创建进程,一般是通过父进程创建的(父子关系)
  • 我们命令行启动的进程都是bash的子进程

查看父子进程 

新的进程创建时操作系统会给每个进程创建一个task_struct(PCB),里面存放着关于这个进程的各种信息、属性等;其中就包括PIDPPID是操作系统内部的数据,操作系统那片文章我们提到用户是无法拿到操作系统内部的数据的要通过系统调用才可以,Linux也给我们提供了相应的函数接口供我们使用。

  • 获取子进程ID:getpid()
  • 获取父进程ID:getppid()

通过man指令可以查询到这两个函数的使用方法。

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 
  5 {
  6     printf("我是一个进程,我的PID为:%d;我的PPID为:%d\n",getpid(),getppid());                                                                                                     
  7     return 0;
  8 }

 

通过编写代码,函数调用获取我们的ID和PPID。 

查询进程的动态目录

Linux操作系统下有一个有一个动态目录结构存放着所有进程;可以通过每个进程的PID查询到这个目录

  • 指令: proc/PID

我们将整个进程的完整目录调出来

更改进程的工作目录

我们可以使用chdir()修改当前工作目录

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 
  5 {
  6     chdir("/root");                                                                   
  7     while(1)
  8     {
  9     printf("我是一个进程,我的PID为:%d;我的PPID为:%d\n",getpid(),getppid());
 10     sleep(1);
 11     }
 12     return 0;
 13 }

 


fork创建进程

fork的引入

在Linux操作系统下有两种创建进程的方式

  • 命令行中直接启动进程(手动启动)
  • 通过代码来创建进程(fork)

我们一直在使用第一种方式创建进程,下面将通过演示fork来创建进程。

fork的使用

man fork 查看fork如何使用

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 
  5 {
  6     printf("我是一个进程,我的PID为:%d;我的PPID为:%d\n",getpid(),getppid());
  7     fork();
  8 
  9     printf("我是一个进程,我的PID为:%d;我的PPID为:%d\n",getpid(),getppid());
 10     sleep(1);                                                                         
 11     return 0;
 12 }

 

运行我们编译好的程序我们发现同一条输出语句运行了两次。这是因为在fork之前只有一个进程,fork创建了一个进程,所以才会执行两次。

fork的原理

fork如何实现的?

fork是一个函数,函数可以设置返回值;当fork子进程成功时给父进程返回子进程的PID,给子进程返回0;fork子进程失败时返回-1;子进程创建成功后会将fork下面的代码拷贝一份,相当有两个进程执行同一份代码,因此会输出两条语句。

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 
  5 {
  6     pid_t id =fork();
  7     if(id<0)
  8     {
  9          return 0;
 10     }
 11     else if ( id == 0 )
 12     {
 13         while(1)
 14         {
 15             printf("我是子进程,我的Pid为:%d,我的PPid为:%d\n",getpid(),getppid());
 16         }
 17         sleep(1);
 18     }
 19     else                                                                              
 20     {
 21 
 22         while(1)
 23         {
 24             printf("我是父进程,我的Pid为:%d,我的PPid为:%d\n",getpid(),getppid());
 25         }
 26         sleep(1);
 27     }
 28     return 0;
 29 }

 

为什么fork之前的代码不执行?

在学习C语言的时候我们知道,代码执行的时候会有一个指针执行一条语句,指针就会随着变化;执行到fork时候,指针也变化到fork语句;因此只能将fork之后的语句拷贝给另一个进程。

为什么要有两个返回值?

这和我们用户使用计算机的场景有关,就像我现在在同一个浏览器里一边在CSDN写着博客,一边还在查找相关的资料。浏览器这一个进程含有两个进程,两个进程做着不同的事情,甚至更多。但是当前我们只能让做相同的事情,执行同一份代码。在以后的学习中我们会通过返回值让他们执行不同的代码片段。


今天对Linux下父子进程和fork进程的介绍分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法。您三连的支持就是我前进的动力,感谢大家的支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-2024华为ICT大赛-计算赛道-广东省省赛初赛-高职组-部分赛题分析【2023.11.18】

2023-2024华为ICT大赛 计算赛道 广东省 省赛 初赛 高职组 部分赛题 分析【2023.11.18】 文章目录 单选题tpcds模式中存在表customer&#xff0c;不能成功删除tpcds模式是&#xff08; &#xff09;以下哪个函数将圆转换成矩形&#xff08; &#xff09;下列哪个选项表示依赖该D…

一键云端,AList 整合多网盘,轻松管理文件多元共享!

hello&#xff0c;我是小索奇&#xff0c;本篇教大家如何使用AList实现网盘挂载 可能还是有小伙伴不懂&#xff0c;所以简单介绍一下哈 AList 是一款强大的文件管理工具&#xff0c;为用户提供了将多种云存储服务和文件共享协议集成在一个平台上的便利性。它的独特之处在于&am…

cesium雷达效果(脉冲圆)

cesium雷达效果(脉冲圆) 下面富有源码 实现思路 使用ellipse方法加载圆型,修改ellipse中‘material’方法重写glsl来实现当前效果 示例代码 index.html <!DOCTYPE html> <html lang="en"><head>

Typora——优雅的排版也是一种品味

电脑中用于编辑文本的软件&#xff0c;一直以来可谓是层出不穷&#xff0c;大家脑海中一定会浮现出很多名字&#xff1a;word&#xff0c;OneNote&#xff0c;记事本&#xff0c;wps&#xff0c;LaTeX&#xff0c;还有各种小众的office工具&#xff0c;等等等等。今天学长将介绍…

java回调函数

在java中是存在回调函数的&#xff0c;我们可以把回调函数理解为一个被作为参数传递的函数。 类似于&#xff0c;我可以设置一个功能给系统&#xff0c;但是只有特定时候才会触发&#xff0c;触发的时候就会把函数作为参数的形式传递到另外的函数中。一般都是使用系统中写好的…

科研学习|科研软件——面板数据、截面数据、时间序列数据的区别是什么?

一、数据采集方式不同 面板数据是通过在多个时间点上对同一组体进行观测而获得的数据。面板数据可以是横向面板数据&#xff0c;即对同一时间点上不同个体的观测&#xff0c;也可以是纵向面板数据&#xff0c;即对同一个体在不同时间点上的观测。采集面板数据需要跟踪相同的个体…

文章分类列表进行查询(实体类日期格式设置)

categoryController GetMappingpublic Result<List<Category>> list(){List<Category> cs categoryService.list();return Result.success(cs);} categoryService //列表查询List<Category> list(); categoryServiceImpl Overridepublic List<Cat…

深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 DeepSORT车辆跟踪3.1 Deep SORT多目标跟踪算法3.2 算法流程 4 YOLOV5算法4.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

kafka入门(一):kafka消息消费

安装kafka&#xff0c;创建 topic&#xff1a; Windows安装kafka, 详情见&#xff1a;https://blog.csdn.net/sinat_32502451/article/details/133067851 Linux 安装kafka&#xff0c;详情见&#xff1a;https://blog.csdn.net/sinat_32502451/article/details/133080353 添…

python的文件目录操作 1

我们在实际开发中&#xff0c;经常需要对文件进行读取、遍历、修改等操作&#xff0c;通过 python 的标准内置os模块&#xff0c;能够以简洁高效的方式完成这些操作。常见的操作整理如下&#xff1a; 文件夹操作&#xff1a;包括文件夹的创建、修改&#xff08;改名/移动&…

redis cluster搭建

k8s部署 Redis Insight k8s部署redis集群_mob6454cc6c6291的技术博客_51CTO博客 占用的内存竟然这么小&#xff0c;才200M左右 随便选个节点进去&#xff0c;看能否连接上其他节点 redis-cli -h redis-cluster-v1-0.redis-cluster.project-gulimall.svc.cluster.local 再创建个…

Typecho用宝塔面板建站(保姆级教程)

提前准备&#xff1a; 1 已备案域名 注意:在腾讯云备案的域名部署阿里云服务器的话还需要在阿里云备案&#xff0c;反之亦然 2 服务器 服务器操作系统设置为windows 服务器实例设置&#xff1a;依次开放8888/888/443/3000-4000/21/22端口 个人用的阿里云&#xff0c;到安全组配…

Python与ArcGIS系列(九)自定义python地理处理工具

目录 0 简述1 创建自定义地理处理工具2 创建python工具箱0 简述 在arcgis中可以进行自定义工具箱,将脚本嵌入到自定义的可交互窗口工具中。本篇将介绍如何利用arcpy实现创建自定义地理处理工具以及创建python工具箱。 1 创建自定义地理处理工具 在arctoolbox中的自定义工具箱…

人充当LLM Agent的工具(Human-In-The-Loop ),提升复杂问题解决成功率

原文&#xff1a;人充当LLM Agent的工具&#xff08;Human-In-The-Loop &#xff09;&#xff0c;提升复杂问题解决成功率 在Agent开发过程中&#xff0c;LLM充当Agent的大脑&#xff0c;对问题进行规划、分解、推理&#xff0c;在执行过程中合理选择利用工具&#xff08;Tool&…

软件工程--软件过程学习笔记

本篇内容是对学校软件工程课堂内容的记录总结&#xff0c;部分也来源于网上查找的资料 软件过程基础 软件过程是指在软件开发过程中&#xff0c;经过一系列有序的步骤和活动&#xff0c;从问题定义到最终软件产品交付和维护的全过程。这个过程旨在确保软件项目能够按时、按预…

jvm 内存模型概述

一、类加载子系统 1、类加载的过程&#xff1a;装载、链接、初始化&#xff0c;其中&#xff0c;链接又分为验证、准备和解析 装载&#xff1a;加载class文件 验证&#xff1a;确保字节流中包含信息符合当前虚拟机要求 准备&#xff1a;分配内存&#xff0c;设置初始值 解析&a…

cesium雷达扫描(雷达扫描线)

cesium雷达扫描(雷达扫描线) 下面富有源码 实现思路 使用ellipse方法加载圆型,修改ellipse中‘material’方法重写glsl来实现当前效果 示例代码 index.html <!DOCTYPE html> <html lang="en"><head>

2.2 调用星火大模型的API

调用星火大模型的API 1 申请API调用权限&#xff1a;2 调用原生星火 API3 统一API调用方式 项目仓库地址&#xff1a;https://github.com/datawhalechina/llm-universe 讯飞星火认知大模型&#xff0c;由科大讯飞于2023年5月推出的中文大模型&#xff0c;也是国内大模型的代表…

Golang环境搭建Win10(简洁版)

Golang环境搭建Win10 Golang环境搭建(Win10)一、前言二、Golang下载三、配置环境变量3.1、配置GOROOT3.2、配置GOPATH3.3、配置GOPROXY代理 Golang环境搭建(Win10) 一、前言 Go&#xff08;又称 Golang&#xff09;是 Google 的 Robert Griesemer&#xff0c;Rob Pike 及 Ken…

Spring Framework 6.1 正式 GA

Spring Framework 6.1在运行时方面针对 JDK 21 和 Jakarta EE 10 上提供了一级支持&#xff0c;同时保留了 JDK 17 和 Jakarta EE 9 基线。Spring 还通过精细的元数据推理跟踪 GraalVM for JDK 21 的演变&#xff0c;同时暂时保持与 GraalVM 22.3 的兼容性。 主要变化 支持 JD…