当前位置: 首页 > news >正文

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux 进程管理 4》(8)

《Linux操作系统原理分析之Linux 进程管理 4》(8)

  • 4 Linux 进程管理
    • 4.4 Linux 进程的创建和撤销
      • 4.4.1 Linux 进程的族亲关系
      • 4.4.2 Linux 进程的创建
      • 4.4.3 Linux 进程创建的过程
      • 4.4.4 Linux 进程的执行
      • 4.4.5 Linux 进程的终止和撤销

4 Linux 进程管理

4.4 Linux 进程的创建和撤销

4.4.1 Linux 进程的族亲关系

1、进程树
在这里插入图片描述
在系统加电启动后,系统只有一个进程,它就是由系统创建的初始进程,又称 init 进程

Init 进程的任务结构体名字为 init_task。Init 进程是系统中所有进程的祖先进程,进程标识号 PID 为 1。

进程之间的父子关系
进程之间的兄弟关系:按照创建时间确定,先者为兄,后者为弟;

2、 Linux 进程的族亲关系
在每个进程的任务结构体中设置了 5 个成员项指针:

Struct task_struct *p_opptr /*指向祖先进程任务结构体指针*/
Struct task_struct *p_pptr /*指向父进程任务结构体指针*/
Struct task_struct *p_cptr /*指向子进程任务结构体指针*/
Struct task_struct *p_ysptr /*指向弟进程任务结构体指针*/
Struct task_struct *p_osptr /*指向兄进程任务结构体指针*/

在任务结构体中只有一个指向子进程指针,它指向该进程子进程中最年轻的一个,其他子进程通过兄弟关系指针与父进程的关系。

4.4.2 Linux 进程的创建

Linux 中,除 init 进程是启动时由系统创建的,其他进程都是由当前进程使用系统调用 fork()创建的。

👉子进程被创建后,通常要继承(共享)父进程所有的资源。包括虚拟存储空间的内容、打开的文件、专用的信号处理程序等。
👉写时拷贝(copy on write)技术:子进程和父进程共享同一个虚拟空间,只是这两个进程中某个进程需要虚拟内存写入时,这时才建立属于该进程的那部分虚拟空间,并把原虚拟空间的那部分内容拷贝到新建的虚拟内存区域中,然后在新建的属于自己的虚拟空间区域中写入信息。 这样既可以使子进程继承父进程的资源,又可以在需要时建立自己的存储空间,避免子进程存储空间的无谓浪费,有效地节省了系统时间。
👉 父进程和子进程在“分裂”后,运行时都在继续执行 fork()程序的代码。但是为了区分两个进程:父进程执行完 fork()时返回值是子进程的 PID 值;而子进程执行 fork()的返回值是 0。

#include <sys/typex.h>
#include <unisd.h>
Main()
{
Pid_t val;
Printf(PID before fork():%d\n”,(int) getpid());
Val=fork();
If(val!=0)
Printf(“parent process PID:%d\n”,(int) getpid());
Else
Printf(“child process PID:%d\n”,(int) getpid());
}
程序执行结果:
PID before fork(): “此时父进程的 PID”
parent process PID: “此时父进程的 PID”
child process PID: “此时子进程的 PID

fork()进程的“分裂”过程
在这里插入图片描述

4.4.3 Linux 进程创建的过程

Linux 中进程都是由当前进程使用系统调用 fork()创建的,而实际上是 fork()中进一步调用内核函数 do_fork()来完成的。Fork()的源代码定义在/kernel/fork.c 中。下面给出 do_fork()内核函数的主要功能:

1)在内存空间为新进程(子进程)分配任务结构体使用的空间,然后把当前进程(父进程)的任务结构体的所有内容拷贝到子进程的任务结构体中。
2)为新进程在其虚拟内存建立内核堆栈。虽然子进程共享父进程的虚拟空间,但是两个进程在进入核心态后必须有自己独立的内核堆栈。
3)对子进程任务结构体中的部分内容进行初始化设置,例如进程的链接关系(族亲关系)等,主要是与父进程不同的那些数据。
4)把父进程的资源管理信息拷贝给子进程,如虚拟内存信息、文件信息、信号信息等,前面说过,这里的拷贝是建立两个进程对这些资源的共享关系。
5)把子进程加入可运行队列中,由调度进程在适当的时机调度运行,也就是在这个时候,当前进程分裂为两个进程。
6)无论哪个进程使用 CPU 运行,都继续执行 do_fork()函数的代码,执行结束后返回它们各自的返回值。

从以上过程可以看出,do_fork()函数的功能首先是建立子进程的任务结构体和对其进行初始化,然后继承父进程资源,最后设置进程的时间片并把它加入可运行队列。

4.4.4 Linux 进程的执行

1、 系统调用 系统调用 exec()
在系统中创建一个进程的目的是需要该进程完成一定的任务,通过执行它实现所需的功能。在 Linux系统中,使进程执行的唯一方法是使用系统调用 exec()。
Exec()由多种使用形式,它们只是在参数上不同,而功能相同。下面介绍一种最常用的形式:

int execl(path,arg0,…,argn,(char*0char *path,*arg0,…,*argn;

👉Path: 指出要执行的程序文件的完整路径名。
👉arg0: 指出要执行的程序文件的文件名。
👉Arg1,…,argn:程序的参数,这些参数的个数可以不同。
👉该系统调用将引起另一个程序的执行,故它成功调用后不需返回,只有在调用失败时,返回值 -1;

例:在程序运行中要执行 linux 命令“ls –l”,程序编制如下:
#include <stdio.h>
Main()
{
Execl(/bin/ls”,”ls”,-l”,0); /*调用成功,则执行 ls 命令*/
Printf(“can only get here on error/n”); /*出错时,返回该程序,显示错误信息*/
}

2.子进程执行新的程序
一个进程使用 fork()建立子进程后,让子进程执行另外一个程序的方法也是通过使用 exec()系统调用。程序的一般形式为:

Main()
{
Pid_t val;
Val =fork();
If(val!=0)
{
…….. /*执行父进程的语句*/
}
Else
{
exec(…..); /*执行程序*/
}
……..
Exit1);
}

Linux 采用“写时拷贝”技术,所以子进程在创建时是共享父进程的正文段和数据段,但是在执行 exec()时,子进程将建立自己的虚拟空间,并把参数 arg0 制定的可执行程序映像装入子进程的虚拟空间,这是就形成了子进程自己的正文段和数据段。

4.4.5 Linux 进程的终止和撤销

进程终止的两种情况:

👉进程完成自身的任务而自动终止:方法 1,使用系统调用 exit()显示终止进程;方法 2,执行到程序的 main()的结尾而隐式地终止进程。
👉进程被内核强制终止:如进程运行出现致命错误,或者收到不能处理的信号时。

1、进程的终止 exit()
Linux 中终止进程是通过调用内核函数 do_exit()实现的,该函数定义在 kernel/exit.c 中。下面结合do_exit()函数的部分源代码对进程终止和撤销的过程说明如下:
1)函数首先设定当前进程的标志,即任务结构体的 flags 成员项设定为 PF_EXITING,表示该进程将要终止

Current->flags = PF_EXITING;
  1. 释放系统中该进程在各个管理队列中的任务结构体。
Del_timer(&current->real_timer);/*从动态计时器系列中释放该进程的任务结构体*/
Sem_exit(); /*从 IPC 进程间通信的信号量机制中释放该进程的任务结构体*/

3)释放进程使用的各种资源。

Kerneld_exit(); /*释放内核*/
_exit_mm(current); /*释放虚拟空间*/
_exit_files(current); /*释放打开的文件*/
_exit_fs(current); /*释放 fs 结构体*/
_exit_sighand(current); /*释放信号*/
Exit_thread(); /*释放线程*/

4)把进程的状态设置为僵死状态。

Current->state = TASK_ZOMBIE

5)把退出码置入任务结构体。

Current->exit_code =code;/*正常退出时,退出码为 0;异常退出时,为非 0 值,通常是错误编号*/

6)变更进程族亲关系。

Exit_notify();/*把要撤销的进程的子进程的父进程赋予 init 进程*/

7)执行进程调度,选择下一个使用 CPU 的进程。

Schedule();

相关文章:

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux 进程管理 4》(8)

《Linux操作系统原理分析之Linux 进程管理 4》&#xff08;8&#xff09; 4 Linux 进程管理4.4 Linux 进程的创建和撤销4.4.1 Linux 进程的族亲关系4.4.2 Linux 进程的创建4.4.3 Linux 进程创建的过程4.4.4 Linux 进程的执行4.4.5 Linux 进程的终止和撤销 4 Linux 进程管理 4.…...

RT-Thread STM32F407 PWM

为了展示PWM效果&#xff0c;这里用ADC来采集PWM输出通道的电平变化 第一步&#xff0c;进入RT-Thread Settings配置PWM驱动 第二步&#xff0c;进入board.h&#xff0c;打开PWM宏 第三步&#xff0c;进入STM32CubeMX&#xff0c;配置时钟及PWM 第四步&#xff0c;回到R…...

idea中把spring boot项目打成jar包

打jar包 打开项目&#xff0c;右击项目选中Open Module Settings进入project Structure 选中Artifacts&#xff0c;点击中间的加号&#xff08;Project Settings->Artifacts->JAR->From modules with dependencies &#xff09; 弹出Create JAR from Modules&#…...

levelDB之基础数据结构-Slice

Slice是levelDB中用于操作字符串的数据结构&#xff0c;以字节为单位。 定义与实现 namespace leveldb {class LEVELDB_EXPORT Slice {public:// Create an empty slice.Slice() : data_(""), size_(0) {}// Create a slice that refers to d[0,n-1].Slice(const c…...

上位机模块之通用重写相机类

在常用的视觉上位机中&#xff0c;我们通常会使用单个上位机匹配多个相机或者多品牌相机&#xff0c;所以在此记录一个可重写的通用相机类&#xff0c;用于后续长期维护开发。 先上代码。 using HalconDotNet; using System.Collections.Generic;namespace WeldingInspection.M…...

机器人导航+OPENCV透视变换示例代码

透视变换又称四点变换&#xff0c;所以不能用于5边形这样的图形变换&#xff0c;不是真正的透视变换&#xff0c;但是这个方法可以把机器人看到的图像转换为俯视图&#xff0c;这样就可以建立地图&#xff0c;要不然怎么建立地图呢。 void CrelaxMyFriendDlg::OnBnClickedOk()…...

KofamScan-KEGG官方推荐的使用系同源和隐马尔可夫模型进行KO注释

文章目录 简介安装使用输入蛋白序列输出detail-tsv格式输出detail格式输出mapper格式 输出结果detail和detail-tsv格式mapper格式常用命令tmp目录 与emapper结果比较其他参数参考 简介 KofamScan 是一款基于 KEGG 直系同源和隐马尔可夫模型&#xff08;HMM&#xff09;的基因功…...

代码随想录算法训练营第五十五天丨 动态规划part16

583. 两个字符串的删除操作 思路 #动态规划一 本题和动态规划&#xff1a;115.不同的子序列 (opens new window)相比&#xff0c;其实就是两个字符串都可以删除了&#xff0c;情况虽说复杂一些&#xff0c;但整体思路是不变的。 这次是两个字符串可以相互删了&#xff0c;这…...

【Linux】kernel与应用消息队列的一种设计

Linux进程间通讯的方式有很多种&#xff0c;这里介绍一种通过消息队列的方式来实现kernel与APP之间的消息收发实现方式&#xff0c;这种方式特别适用于&#xff0c;kernel中发送消息&#xff0c;应用层收取消息。 消息队列设备驱动 该方法的设计思路即是创建一个消息队列的设…...

我们常说的网络资产,具体是如何定义的?

文章目录 什么叫网络资产&#xff1f;官方定义的网络资产网络资产数字化定义推荐阅读 什么叫网络资产&#xff1f; 通过百度查询搜索什么叫网络资产&#xff1f;大体上都将网络资产归类为计算机网络中的各类设备。 基本上会定义网络传输通信架构中用到的主机、网络设备、防火…...

WPF中可冻结对象

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;"可冻结对象"指的是那些在创建之后可以被设置为不可更改状态的对象。这种特性允许这些对象更有效地被共享和复制&#xff0c;并且可以增加性能。 例如&#xff0c;Brushes&#xff0c;P…...

【人工智能实验】A*算法求解8数码问题 golang

人工智能经典问题八数码求解 实际上是将求解转为寻找最优节点的问题&#xff0c;算法流程如下&#xff1a; 求非0元素的逆序数的和&#xff0c;判断是否有解将开始状态放到节点集&#xff0c;并设置访问标识位为true从节点集中取出h(x)g(x)最小的节点判断取出的节点的状态是不…...

Kafka学习笔记(二)

目录 第3章 Kafka架构深入3.3 Kafka消费者3.3.1 消费方式3.3.2 分区分配策略3.3.3 offset的维护 3.4 Kafka高效读写数据3.5 Zookeeper在Kafka中的作用3.6 Kafka事务3.6.1 Producer事务3.6.2 Consumer事务&#xff08;精准一次性消费&#xff09; 第4章 Kafka API4.1 Producer A…...

Typora for Mac:打造全新文本编辑体验

Typora for Mac是一款与众不同的文本编辑器&#xff0c;它不仅拥有直观易用的界面&#xff0c;还融合了Markdown语法和富文本编辑的功能&#xff0c;为用户带来了前所未有的写作和编辑体验。 一、简洁明了的界面设计 Typora for Mac的界面简洁明了&#xff0c;让用户可以专注…...

TikTok与媒体素养:如何辨别虚假信息?

在当今数字时代&#xff0c;社交媒体平台如TikTok已经成为信息传播和社交互动的主要渠道之一。然而&#xff0c;随之而来的是虚假信息的泛滥&#xff0c;这对用户的媒体素养提出了严峻的挑战。本文将探讨TikTok平台上虚假信息的现象&#xff0c;以及如何提高媒体素养&#xff0…...

Spring Boot 中使用 ResourceLoader 加载资源的完整示例

ResourceLoader 是 Spring 框架中用于加载资源的接口。它定义了一系列用于获取资源的方法&#xff0c;可以处理各种资源&#xff0c;包括类路径资源、文件系统资源、URL 资源等。 以下是 ResourceLoader 接口的主要方法&#xff1a; Resource getResource(String location)&am…...

1688往微信小程序自营商城铺货商品采集API接口

一、背景介绍 随着移动互联网的快速发展&#xff0c;微信小程序作为一种新型的电商形态&#xff0c;正逐渐成为广大商家拓展销售渠道、提升品牌影响力的重要平台。然而&#xff0c;对于许多传统企业而言&#xff0c;如何将商品信息快速、准确地铺货到微信小程序自营商城是一个…...

QStatusBar开发详解

一、QStatusBar接口说明 QStatusBar 类是 Qt 中用于创建和管理状态栏的类。它继承自 QFrame 类&#xff0c;提供了在主窗口底部显示消息、进度等信息的功能。以下是一些 QStatusBar 类的重要接口&#xff1a; 1.1 QStatusBar构造函数 QStatusBar(QWidget *parent nullptr);…...

后端接口性能优化分析-程序结构优化

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…...

【SpringBoot3+Vue3】三【实战篇】-后端(优化)

目录 一、登录优化-redis 1、SpringBoot集成redis 1.1 pom 1.2 yml 1.3 测试程序&#xff08;非必须&#xff09; 1.4 启动redis&#xff0c;执行测试程序 2、令牌主动失效&#xff08;代码优化&#xff09; 2.1 UserController设置token到redis 2.2 登录拦截器Log…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...