【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写着博客,一边还在查找相关的资料。浏览器这一个进程含有两个进程,两个进程做着不同的事情,甚至更多。但是当前我们只能让做相同的事情,执行同一份代码。在以后的学习中我们会通过返回值让他们执行不同的代码片段。

 

相关文章
|
12天前
|
存储 安全 Linux
|
1月前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
169 2
|
14天前
|
Linux Shell 数据安全/隐私保护
|
1月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
1月前
|
网络协议 Linux
linux学习之套接字通信
Linux中的套接字通信是网络编程的核心,允许多个进程通过网络交换数据。套接字提供跨网络通信能力,涵盖本地进程间通信及远程通信。主要基于TCP和UDP两种模型:TCP面向连接且可靠,适用于文件传输等高可靠性需求;UDP无连接且速度快,适合实时音视频通信等低延迟场景。通过创建、绑定、监听及读写操作,可以在Linux环境下轻松实现这两种通信模型。
34 1
|
1月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
1月前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第5天】麒麟系统mate-indicators进程占用内存过高问题解决
128 0
|
安全 Linux 调度
关于linux系统如何实现fork的研究(二)【转】
转自:http://www.aichengxu.com/linux/7166015.htm 本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言   前一篇关于linux系统如何实现fork的研究(一)通过代码已经说明了从用户态怎么通过软中断实现调用系统调用clone函数,而clone函数的精华copy_process函数就在此篇文章中进行分析。
1027 0
|
Linux C语言
关于linux系统如何实现fork的研究(一)【转】
转自:http://www.aichengxu.com/linux/4157180.htm 引言 fork函数是用于在linux系统中创建进程所使用,而最近看了看一个fork()调用是怎么从应用到glibc,最后到内核中实现的,这片文章就聊聊最近对这方面研究的收获吧。
1083 0
|
3天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
18 3