[Linux进程(一)] 什么是进程?PCB的底层是什么?以及进程标识符pid与ppid

news2024/10/5 15:38:18

在这里插入图片描述

文章目录

  • 1、前言
  • 2、描述进程 — PCB(os怎么管理进程呢)
  • 3、查看进程
    • 3.1 方法一
    • 3.2 方法二
  • 4、系统调用获取进程标示符(PID)
    • 4.1 获取进程的ID
    • 4.2 获取进程的父进程ID
  • 5、系统调用创建子进程-fork

1、前言

大家经常都在讲进程,而它到底是什么呢?
这里给大家先简单的介绍一下:

  • 课本概念:程序的一个执行实例,正在执行的程序等。
  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。

2、描述进程 — PCB(os怎么管理进程呢)

在操作系统中我们说到,os管理的本质并不是对事物本体的管理,而是对数据的管理。
这里虽然我们并不知道进程是什么,但是按照上面的理解,我们对进程的管理,也是对进程的数据进行管理,这里就用到那六个字“先描述,再组织”。我们来画图理解一下:
在这里插入图片描述
操作系统可能会同时管理非常多的“进程”,因此在管理的时候,管理这些进程的数据即可,将这些进程共有的属性提取出来,用结构体将其存起来,再使用链表将其链接起来,这样就能有效的管理进程,这样的机制就叫做“先描述,再组织”。
这个进程属性的集合就叫做PCB,也叫做进程控制块。
PCB是一个统称,在Linux中,PCB叫做 task_struct。
最终,我们操作系统对PCB的管理就被建模成了对链表的增删查改。
我们得出:进程 = 可执行程序 + 内核数据结构

3、查看进程

3.1 方法一

在Linux下我们可以使用下面的这个命令来查看进程:

ps ajx

在这里插入图片描述
这是所有的进程,如果我们只是对其中一个进程查看呢?我们看下面的:
我们先写一段C语言程序,编译为可执行程序并执行,然后使用该命令来查看一下进程:

#include <stdio.h>
#include <unistd.h>
 
int main()
{
    while(1)
    {
        printf("我是一个进程\n");
        sleep(1);
    }
 
    return 0;
}

在这里插入图片描述
命令:

ps ajx | grep mycode

这里用到我们以前学到的 管道符与过滤,筛选出我们想找的进程。

3.2 方法二

我们可以通过根目录下的proc目录来查看。proc目录下保存有进程的信息。
在这里插入图片描述

proc目录下的蓝色数字就是每一个进程的pid(Process ID),这就跟我们的身份证号一样,一人只有一个,每个进程都只有这么一个标识符。
我们再次以刚才那段C语言为例,来查看进程:
在这里插入图片描述
在这里插入图片描述
如果我们删掉磁盘上可执行程序,进程没有终止的话,我们仍然是可以查到的,因为进程是程序拷贝到内存中的,代码+数据都被拷贝下来了,所以删掉磁盘上的可执行程序不会影响的。
在这里插入图片描述
当终止掉程序,内存中拷贝的可执行程序与数据都被释放掉了,因此再去查就查不出来了。
在这里插入图片描述

4、系统调用获取进程标示符(PID)

  • 进程id(PID)
  • 父进程id(PPID)
    我们在上面使用 ps ajx 命令的时候发现,有一个PID,还有一个PPID,我们不难猜到,这些都是PCB中的属性。
    如果获取呢?这里要介绍我们第一个要学习系统调用,getpid与getppid了。我们使用man手册查一下看看怎么说。
    在这里插入图片描述
    我们接下来就使用getpid与getppid系统调用接口来看看能不能查到pid与ppid。

4.1 获取进程的ID

这里我们写一段C语言程序来调用看看:

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

编译后我们运行可执行程序,并使用下面 ps ajx 命令来对比看,pid是否正确。

ps ajx | head -1 && ps ajx | grep mycode | grep -v grep

在这里插入图片描述
我们发现,getpid确实是没错的,并且我们调用是没有出错的。
当我们想要终止掉一个进程的时候,我们总是用 ctrl + c,今天我们再来学一个终止命令,kill 命令。

kill -9 pid  // 这里的9是9号信号

在这里插入图片描述

4.2 获取进程的父进程ID

我们继续改写上面的C语言代码,再来看看 getppid() 系统调用接口。

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

在这里插入图片描述
经过我的不断调用发现,每次运行pid都是在变化的,但是ppid确实一直没有变化,我猜它是一直在运行的,我们来查看一下它是谁。
在这里插入图片描述
原来它是命令行解释器 bash 呀。我们由此也知道了,我们所敲出来的命令都是 bash 的子进程。
那我们Linu下有没有创建子进程的系统接口呢,有,我们再来学一下。

5、系统调用创建子进程-fork

我们可以使用fork创建子进程,先查一下man手册看看:
在这里插入图片描述
我们写一份 C语言代码来试着调用系统接口 fork()。
我们先想一下,我们有自己的进程为什么还要去创建子进程呢?
在上面的学习我们看到,我们输入的命令是执行命令得到结果,而父进程bash是解释你所输入的命令,这就说明,我们父子进程各自做各自的事。由此,我们想是不是可以,按照fork的返回值配合 if-else 语句来执行不同的事。我们试一下:

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

int main()
{
    printf("我是一个父进程,我的pid:%d\n", getpid());
     
    pid_t id = fork();
    // fork之后用if分流
    if(id < 0) return -1;
    else if(id == 0)
    {
        // child
        while(1)
        {                
            printf("我是子进程,pid:%d, ppid:%d\n", getpid(), getppid());
            sleep(1);                                                             
        }
    }
    else 
    {
        // parent
    	while(1)
        {
            printf("我是父进程,pid:%d, ppid:%d\n", getpid(), getppid());
            sleep(1);
        }
	}

    return 0;
}

我们编译后运行可执行程序。
在这里插入图片描述

通过打印出来的结果,我们发现刚我们的猜测是正确的!!!
这里我们可以总结出几个问题,对fork作以总结:
1、fork干了什么事情?
调用fork()后,创建了子进程,父子进程可以协作,干不同的事。
2、为什么fork会有两个返回值?
我们在查文档的时候,就有返回值的介绍。
成功时,给父进程返回子进程的pid,给子进程返回0;失败时,给父进程返回-1,不创建子进程。
fork之后代码共享,fork函数执行两次就有两个返回值,一次返回父进程接收,另外一次返回子进程接收。
3、为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?
我们与现实生活联系起来。现实中,父 : 子 = 1 : n(n >= 1),父亲给孩子不同名字,可以更好的区分孩子(保证唯一性)。这样类比到这里,给父进程返回子进程的pid,父进程必须有标识子进程的方式,而子进程只需要知道自己是否被创建成功,以及知道父进程是谁即可 (调用 getppid())。
4、fork之后谁先运行?
我们上面运行了可执行程序后,发现先跑了父进程的代码片段,然后跑子进程的代码片段,但是后面并不是这样的规律。
当创建完子进程后,系统的其他进程,以及父进程和子进程都要被调度。父子进程的PCB都被创建并在运行队列中排队,哪个进程的PCB先被调度,哪个进程就先被运行,是由操作系统决定的,不确定的。
5、如何理解同一个id变量,怎么会有不同的值?
当父子进程都被运行时,他们共用一份代码与数据,但是一旦发生数据的写入,就会发生写时拷贝,数据就不再共享,而是父子进程各一份自己的数据,因此就会出现同一个变量,值不相同。

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

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

相关文章

x-cmd pkg | dua - 磁盘使用分析器

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 dua 是 Disk Usage Analyzer 的简写&#xff0c;该工具可以快速查看给定目录的磁盘空间使用情况。 对于想要深入了解磁盘空间使用情况并有效管理存储的用户来说&#xff0c;Dua 是一个很有价值的工具。通过使用 Dua …

Java流程控制的陷阱

文章目录 1. switch中break的作用2. switch支持的数据类型3. else隐含的条件4. 省略花括号的陷阱5. for循环的结构6. 使用标签跳出双层for循环 流程控制三种&#xff1a;顺序结构、分支结构、循环结构 分支机构两种&#xff1a;if语句、switch语句 循环结构&#xff1a;while循…

每日一篇英语文章分享:I have a dream. 争取早日阅读论文自由.

我有一个梦想》&#xff08;英文&#xff1a;I have a dream&#xff09;是美国黑人民权运动领袖马丁路德金于1963年8月28日在华盛顿林肯纪念堂发表的纪念性演讲。 《我有一个梦想》是马丁路德金在美国黑人受种族歧视和迫害由来已久的背景下&#xff0c;为了推动美国国内黑人争…

安达发|APS智能排产软件有哪些条件约束功能

APS智能排产软件是一种基于先进算法和人工智能技术的生产计划与调度系统&#xff0c;它可以帮助企业实现生产资源的优化配置&#xff0c;提高生产效率和降低生产成本。在实际应用中&#xff0c;APS智能排产软件需要满足多种条件约束功能&#xff0c;以满足不同企业的需求。以下…

python 和shell 变量互相传递

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 主要介绍python和shell变量互相传递方法&#xff0c;使用了环境变量、管道等方法。 python -> shell&#xff1a; 1.环境变量 import os var123或var123 o…

【手搓深度学习算法】用线性回归预测波士顿房价

线性回归 线性回归是一种监督学习方法&#xff0c;用于建立因变量与一个或多个自变量之间的关系。线性回归的目标是找到一条直线&#xff0c;使得所有数据点到这条直线的距离之和最小。 线性回归的基本形式如下&#xff1a; y β 0 β 1 x 1 β 2 x 2 . . . β n x n ϵ…

Linux学习之网络编程(纯理论)

写在前面 刚刚更新完Linux系统编程&#xff0c;特别推荐大家去看的Linux系统编程&#xff0c;总共44个小时&#xff0c;老师讲的非常好&#xff0c;我是十天肝完的&#xff0c;每天大概看20集&#xff0c;每天还要以写blog的形式来写笔记来总结一下&#xff0c;虽然这十天有点…

printk的使用与理解

文章目录 一、理清printk二、printk的使用三、printk的打印级别1、基本解释2、详细解释3、如何修改console_loglevel、default_message_loglevel、minimum_console_loglevel、default_console_loglevel的值 四、printk的输出地方五、其它 一、理清printk printk如何使用&#…

C++ 实现十大排序算法

教你手撕排序&#xff0c;这里有一个概念就是稳定排序。假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#xff0c;这些记录的相对次序保持不变&#xff0c;即在原序列中&#xff0c;r[i]r[j]&#xff0c;且r[i]在r[j]之前&#…

vim升级和配置

vim升级和配置 1、背景2、环境说明3、操作3.1 升级VIM3.2 配置VIM3.2.1、编辑vimrc文件3.2.2、安装插件 1、背景 日常工作跟linux系统打交道比较多&#xff0c;目前主要用到的是Cenots7和Ubuntu18这两个版本的linux系统&#xff0c;其中Centos7主要是服务器端&#xff0c;Ubun…

图神经网络|5.消息传递的计算方法 6.多层GNN的作用

5.消息传递的计算方法 边的存放方式 注意&#xff0c;在实际的边的实现方式中&#xff0c;并不是以邻接矩阵来进行实现的&#xff0c;这是因为在图的更新中&#xff0c;用邻接矩阵进行更新所占用的时间开销相对大&#xff0c;二是因为领接矩阵占用的空间大&#xff08;N方&am…

java数据结构与算法刷题-----LeetCode343. 整数拆分(TODO)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难&#xff0c;但它就是固定套路而已。其实动态规划只…

Apache JMeter 5.5: 新手指南

如何获取并运行 JMeter 首先&#xff0c;要使用 JMeter&#xff0c;你需要从官网获取软件包。前往 Apache JMeter 的官方页面&#xff0c;然后下载所 需的压缩文件。 配置和启动 JMeter 获取了 JMeter 后&#xff0c;由于它是无需安装即可使用的工具&#xff0c;直接解压下载…

Linux Capabilities 进阶实战

目录 1. 快速回顾 2. 为可执行文件分配 capabilities 3. 构建半特权环境 4. 容器与 capabilities Linux Capabilities 基础概念与基本使用 上一篇学习了LinuxCapabilities的基础知识和基本使用&#xff0c;因为后面需要学习Docker的逃逸&#xff0c;理解Linux Capabilitie…

多模态+SNN个人学习历程和心得

祖传开头 这次想写一个一直深藏心中的研究方向&#xff0c;那就是多模态方向。其实当初在实验室那会儿&#xff0c;最先接触的就是多模态的工作&#xff0c;因此这是我科研之路的起点。只不过&#xff0c;后来经历了一些波折&#xff0c;导致个人没有往这个方向深挖&#xff0…

终端输入命令无法自动换行,且命令会覆盖掉前面的内容

目录 问题描述原因分析&#xff1a;解决方案&#xff1a;补充内容&#xff1a; 问题描述 进入到容器内部之后&#xff0c;在终端输入命令&#xff0c;当命令长一些的时候&#xff0c;会出现命令无法自动换行&#xff0c;而且 会覆盖掉之前的命令&#xff0c;继续写虽然不可以正…

基于大数据机器学习TF-IDF 算法+SnowNLP的智慧旅游数据分析可视化推荐系统

文章目录 基于大数据机器学习TF-IDF 算法SnowNLP的智慧旅游数据分析可视化推荐系统一、项目概述二、机器学习TF-IDF 算法什么是TF-IDF&#xff1f;TF-IDF介绍名词解释和数学算法 三、SnowNLP四、数据爬虫分析五、项目架构思维导图六、项目UI系统注册登录界面各省份热门城市分析…

Buzz 离线音频转字幕工具(完全免费,无需登录)

关于 Buzz Buzz 是一款可以自动识别语音为文本字幕的软件工具&#xff0c;基于 OpenAI 开源的 Whisper 自动语音识别模型&#xff0c;可以批量将音频或者是视频中的内容自动转化为带有时间的字幕&#xff0c;速度非常快&#xff0c;是一款能极大提高效率的生产力小工具。 Bu…

排队免单?买东西花了钱还能拿回来?——工会排队模式

随着互联网和电子商务的迅猛发展&#xff0c;消费者的购物需求和期望也在不断升级。为了满足这一需求&#xff0c;工会排队模式作为一种创新消费体验模式应运而生。 工会排队模式是一种颠覆传统的电商模式&#xff0c;它通过向消费者返还现金的方式&#xff0c;重新定义了购物体…

使用Java版工程行业管理系统源码,提升工程项目的综合管理能力

工程项目管理涉及众多环节和角色&#xff0c;如何实现高效协同和信息共享是关键。本文将介绍一个采用先进技术框架的Java版工程项目管理系统&#xff0c;该系统支持前后端分离&#xff0c;功能全面&#xff0c;可满足不同角色的需求。从项目进度图表到施工地图&#xff0c;再到…