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

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

父子进程

父子进程的引入

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

aeee182cf6df4cc49286ba4b11f03114.png

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

 d13b7bfcb6824bebbdd50eeb3ed35592.png

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

 

1f84ebb0b77946098b54efbda08e3ccc.png

总结:

·       启动进程本质就是创建进程,一般是通过父进程创建的(父子关系)

·       我们命令行启动的进程都是bash的子进程

查看父子进程

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


·       获取子进程ID:getpid()

·       获取父进程ID:getppid()

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

ab4b59ce87e240798e62ea70e6c3d6b0.png

  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 }

7dc70460c9da4b46bc5c5167e9d0947b.png

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


查询进程的动态目录

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

·       指令: proc/PID

 

3993059dc01047fdb42c6c0fa465ab7b.png

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

166442b4bab4493a8e9bf17475335cf9.png

更改进程的工作目录

我们可以使用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 }

 6c5af035a3094fcc8350431a6dddd301.png

fork创建进程

fork的引入

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

·       命令行中直接启动进程(手动启动)

·       通过代码来创建进程fork

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

fork的使用

man fork 查看fork如何使用

 dc8b01aa660a4474b3da8c105c525644.png

  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 }

ba3a19cf4b5d483f806d1a2652aa9fab.png

运行我们编译好的程序我们发现同一条输出语句运行了两次。这是因为在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 }

03e31991a00a4aeb98820a79a7a5ab7d.png

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

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

为什么要有两个返回值?

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

 

相关文章
|
4天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
22 3
|
4天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
17 2
|
5天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
41 8
|
4天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
21 3
|
7天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
24 6
|
7天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
33 6
|
8天前
|
机器学习/深度学习 自然语言处理 Linux
Linux 中的机器学习:Whisper——自动语音识别系统
本文介绍了先进的自动语音识别系统 Whisper 在 Linux 环境中的应用。Whisper 基于深度学习和神经网络技术,支持多语言识别,具有高准确性和实时处理能力。文章详细讲解了在 Linux 中安装、配置和使用 Whisper 的步骤,以及其在语音助手、语音识别软件等领域的应用场景。
36 5
|
8天前
|
缓存 运维 监控
【运维必备知识】Linux系统平均负载与top、uptime命令详解
系统平均负载是衡量Linux服务器性能的关键指标之一。通过使用 `top`和 `uptime`命令,可以实时监控系统的负载情况,帮助运维人员及时发现并解决潜在问题。理解这些工具的输出和意义是确保系统稳定运行的基础。希望本文对Linux系统平均负载及相关命令的详细解析能帮助您更好地进行系统运维和性能优化。
26 3
|
8天前
|
监控 网络协议 算法
Linux内核优化:提升系统性能与稳定性的策略####
本文深入探讨了Linux操作系统内核的优化策略,旨在通过一系列技术手段和最佳实践,显著提升系统的性能、响应速度及稳定性。文章首先概述了Linux内核的核心组件及其在系统中的作用,随后详细阐述了内存管理、进程调度、文件系统优化、网络栈调整及并发控制等关键领域的优化方法。通过实际案例分析,展示了这些优化措施如何有效减少延迟、提高吞吐量,并增强系统的整体健壮性。最终,文章强调了持续监控、定期更新及合理配置对于维持Linux系统长期高效运行的重要性。 ####
|
13天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
46 4