当前位置: 首页 > 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…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...

MySQL基本操作(续)

第3章&#xff1a;MySQL基本操作&#xff08;续&#xff09; 3.3 表操作 表是关系型数据库中存储数据的基本结构&#xff0c;由行和列组成。在MySQL中&#xff0c;表操作包括创建表、查看表结构、修改表和删除表等。本节将详细介绍这些操作。 3.3.1 创建表 在MySQL中&#…...

解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护

摘要 本文以健康管理应用为例&#xff0c;展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制&#xff0c;实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码&#xff0c;演示鸿蒙系统如何平衡功能需求与隐私安…...