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

【Linux】进程控制

🌟🌟作者主页:ephemerals__

🌟🌟所属专栏:Linux

目录

前言

一、什么是进程控制

二、进程创建

三、进程终止(进程退出)

退出码

main函数返回

_exit()

exit()

测试

四、进程等待 

wait

waitpid

注意事项

wait和waitpid的输出型参数

五、进程程序替换

进程替换相关接口

总结


前言

        在现代计算中,操作系统负责管理硬件资源并为应用程序提供一个稳定的运行环境。Linux作为一种广泛使用的类Unix操作系统,它的进程管理功能至关重要。Linux提供了强大的进程控制机制和接口,帮助我们管理进程的生命周期、资源分配和调度。在这篇博客中,我们将深入探讨Linux进程控制的基础知识以及从四个方面(进程创建、进程终止、进程等待、进程程序替换)介绍常用的进程控制相关API接口,帮助大家更好地理解和掌握Linux系统中的进程控制技术。

一、什么是进程控制

        进程控制是操作系统中管理和调度进程的关键功能,涉及到进程的创建、终止、等待、程序替换以及进程间通信等多个方面,简而言之,进程控制确保操作系统能够有效地管理并协调不同程序的执行。对于我们而言,要对进程进行相关操作,就要深入理解操作系统对进程的控制机制,并熟悉Linux下进程控制的相关接口

二、进程创建

        在Linux下,我们通常使用fork函数完成进程的创建。创建后的新进程称之为子进程,而当前进程叫做父进程。博主已经在以下两篇文章中,对进程创建的底层原理、fork的使用方法、注意事项以及写时拷贝的原理进行了详细的讲解,大家参阅这两篇文章即可,这里就不再复述。

 【Linux】进程概念和进程状态-CSDN博客

【Linux】深入理解程序地址空间-CSDN博客 

三、进程终止(进程退出)

        一个进程在做完相应工作后,需要执行“终止”操作,其本质是释放进程的task_struct及其对应的代码和数据。 进程终止的常见情况有四种:

1. main函数返回

2. 调用_exit()退出

3. 调用exit()退出

4. 给进程发送信号(如kill()、ctrl + c)

前三种情况都用于当前正在执行的进程退出,属于进程的正常退出,而最后一种专门用于杀死其他进程,属于异常退出。本文博主会详细介绍前三种退出方法的使用及其原理,至于最后一种,博主后续会结合信号一起讲解。

退出码

         进程退出时,都会返回一个“退出码”,它本质是一个整数,用于表示程序的执行情况。例如,我们在VSCode终端输入指令时,可以看出它是否执行成功,本质就是通过识别对应程序的退出码来完成的:

不同的退出码,所表示的退出状态也不尽相同。只有退出码为0时,表示成功执行,且执行的结果正确,其他退出码均表示执行失败或结果不符合预期,原因各异

以下是常见的退出码所表示的执行情况:

注意:要将“程序成功执行”和“程序执行的结果正确”区分开,退出码非0并不代表程序一定是异常退出的,也有可能成功执行,但结果不符合预期。而异常退出是说程序执行时遇到异常,直接终止了,没有符不符合预期的概念了。

如下指令可以打印最近执行结束的程序的退出码,便于我们判断退出状况:

echo $?

main函数返回

        main函数return返回是最常见的进程退出方法,再程序执行完毕后,使用return返回即可。main函数的返回值即是程序的退出码

_exit()

        _exit() 是一个系统调用,当程序执行到调用处时,会直接退出。它的函数原型如下:

#include <unistd.h>void _exit(int status);

参数status表示程序的退出码,当出现错误,我们可以使用该接口配合退出码退出程序。

_exit是一种低级的退出操作,退出时不会进行任何其他处理,只会返回退出码,所以一般是用于多进程编程时的子进程错误退出。

注:传入的退出码虽然类型为int,但退出码的取值范围是0~255,所以只会取int的最低8位。

exit()

        exit() 是c标准库的函数,包含在<stdlib.h>头文件中,相比_exit更加常用。其函数原型:

#include <stdlib.h>void exit(int status);

参数status也表示程序退出码。

实际上,exit的底层调用了_exit,不过在退出之前做了一系列清理工作,例如刷新 I/O 缓冲区,确保所有的输出数据都被写入到相应的文件或终端、关闭文件描述符、间接释放动态分配的内存等。

测试

        接下来我们做一段测试,写一个简单的程序,调用exit退出,并将50作为退出码,然后在命令行打印退出码:

#include <stdio.h>
#include <stdlib.h>int main()
{printf("hello world\n");exit(50);
}

执行程序并打印退出码:

可以看到,程序打印后退出,并且返回了退出码50。

四、进程等待 

        在之前的文章中提到,一个子进程在退出后,需要父进程回收资源,如果父进程一直不回收,那么子进程的PCB就会一直存在,导致出现僵尸进程。另外进程退出时返回的退出码需要被父进程获取,才能判断子进程的执行情况。

因此,“进程等待”的作用是:

1. 回收子进程,释放子进程的资源(必须完成)

2. 获取子进程的退出信息(可选)

在Linux下,我们通常使用waitwaitpid进行进程等待。

wait

        wait是一个函数,在父进程中使用,作用是等待子进程退出后,回收子进程资源,并获取子进程的退出码与其他退出状态。它的函数原型如下:

#include <sys/wait.h>pid_t wait(int *status);

参数status:是一个输出型参数,表示子进程的退出信息。具体细节在waitpid之后统一介绍。

返回值:如果回收成功,返回子进程的PID。如果失败,返回 -1。

如果父进程有多个子进程,那么wait就会等待任意一个子进程。

注意:调用wait等待子进程时,如果此时子进程还在执行自己的程序,并未退出,那么父进程就会一直阻塞在wait的调用处,直到子进程退出,再执行后续代码。

waitpid

        相比wait,函数waitpid的功能更加丰富,因此也更加常用。 它的函数原型如下:

#include <sys/wait.h>pid_t waitpid(pid_t pid, int *stat_loc, int options);

参数pid:如果传入-1,会等待任意子进程(有多个子进程的情况下);如果传入一个大于0的数,表示专门等待子进程PID为pid的子进程。

参数stat_loc:输出型参数,表示子进程的退出信息。具体细节稍后介绍。

参数options:通常传入0,表示阻塞等待(即子进程退出之前阻塞)。如果传入宏WNOHANG,则表示:若子进程还未退出,不等待,直接返回0(可以配合循环进行多次的非阻塞轮询,非阻塞轮询期间的空闲时间可以被利用,让父进程完成自己的任务

返回值:如果回收成功,返回子进程的PID。如果失败(例如没有对应的pid),返回 -1。如果第三个参数传WNOHANG并且子进程还未退出,返回0。

注意事项

1. 调用wait/waitpid时,如果子进程已经退出而没有被回收,那么函数会立即返回,释放子进程资源,获取退出信息。

2. 调用wait/waitpid时,如果子进程已经被回收,那么就会等待失败,立即返回 -1。

3. 如果父进程不调用wait或waitpid,子进程在退出后会变成僵尸进程。

wait和waitpid的输出型参数

        wait和waitpid都有一个输出型参数,都用于表示子进程的退出信息。这个信息并不只是单纯的退出码,其中还包含了收到信号导致退出时的信号编号退出方式等信息。当然,这些东西具体是什么,我们无需关心,后续在讲解信号时博主会进行分析。现在我们终点关注的是:输出型参数只是一个整数,却包含了多种信息,那势必要对其进行划分,我们了解了划分方式,才能从其中提取出退出信息

        它的划分方式如下:

1. 如果子进程正常退出,那么输出型参数的0~7位全为0,8~15位是退出码;

2. 如果子进程异常退出,那么输出型参数0~6位表示信号编号,第7位表示异常退出方式,8~15位的数据没有使用价值。

获取到输出型参数后,我们可以进行相应的位运算处理,得到退出码或者其他信息。当然,有几个宏可以帮助我们直接求出退出码等信息(传入输出型参数的值即可):

WIFEXITED() 用于判断子进程是否是正常退出。

WEXITSTATUS() 可以求出退出码。

WTERMSIG() 可以求出异常退出时的信号编号。

当然,如果我们不关心子进程的退出状况,可以在输出型参数位置传NULL。

父进程回收子进程,并获取子进程退出信息的过程:子进程退出时,其退出信息会存入其PCB中,当被父进程回收时,在子进程PCB中读取,然后释放子进程的PCB。

五、进程程序替换

         进程程序替换指的是一个进程在运行过程中,用新的程序代码替换当前执行的代码,然后执行新程序的代码。如果我们创建了一个进程,想要这个进程执行一个全新的程序,就可以使用进程程序替换。

        发生进程替换后,PCB的内容不变,也没有创建新的进程,而是当前进程对应物理内存中的代码、数据、堆区栈区全部被目标代码和数据覆盖

进程替换相关接口

        Linux下,实现进程替换最常用的是exec系列函数,一共有六个:

#include <unistd.h>int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);

这六个函数都是用于替换当前程序的代码和数据,只是传参方式有所不同,功能略有差别。

首先介绍一下它们的返回值:

如果替换成功,直接执行新代码,后续的原代码已经被替换,不再执行,因此没有返回值。

如果替换失败,返回 -1。

所以对于exec系列函数,无需检查其返回值,因为只要返回就失败。

再来谈谈它们的参数:

1. 上述函数中,叫做path的参数,一律传入的是一个字符串,表示目标程序的路径+程序名

2. 叫做file的参数,一律传入目标程序的程序名(路径会自动到环境变量PATH中查找)。

3. 叫做arg的参数,是一个可变参数,一个一个地传入目标程序的命令行参数字符串(注意程序名算第一个命令行参数;最后一个命令行参数须是NULL)。当然,如果不需要使用其他的命令行参数,只需传一个程序名和一个NULL即可。

4. 叫做argv[]的参数,将指向所有命令行参数字符串的指针数组的数组名传入(注意程序名算第一个命令行参数;指针数组的最后一个元素须是NULL),也就是传命令行参数的另一种方式。

5. 带有参数envp[]的函数,表明替换的进程要使用该函数传入的全新的环境变量。因此,该参数处要传入指向所有环境变量字符串的指针数组的数组名(注意环境变量格式是"环境变量=值";指针数组的最后一个元素须是NULL)。

以上七个函数的名字十分相似,容易混淆,但其实它们也有规律,博主给大家列出来方便记忆:

1. 函数名带"l"的,表示命令行参数要一个个地传入;而带"v"的表示命令行参数要用指针数组的方式传入。

2. 函数名带"p"的表示目标程序不用带路径,会自动在PATH中查找。

3. 函数名带"e"的表示可以给目标程序设置新的环境变量。 

当然,除了这六个函数,还有一个系统调用execve,使用方法和execvpe完全相同。原型如下:

#include <unistd.h>int execve(const char *filename, char *const argv[], char *const envp[]);

写一个简单的调用示例,看看这些函数的调用区别:

#include <unistd.h>int main()
{//假如要将程序替换为/usr/bin路径下的ls指令,并加上选项-l//并且对于支持修改环境变量的函数,修改环境变量PATHchar* const argv[] = {"ls", "-l", NULL};char* const envp[] = {"PATH=/usr/bin", NULL};execl("/usr/bin/ls", "ls", "-l", NULL); // 带l要一个个传入命令行参数execlp("ls", "ls", "-l", "NULL"); // 带p不用传路径execle("usr/bin/ls", "ls", "-l", NULL, envp); // 带e要传环境变量表execv("/usr/bin/ls", argv); // 带v要用指针数组传入命令行参数execvp("ls", argv); // 带p不用传路径;带v用指针数组传命令行参数execvpe("ls", argv, envp); // 带p不用传路径;带v用指针数组传命令行参数;带e要传环境变量表execve("ls", argv, envp);return 0;
}

实际上,exec系列接口中,六个标准库函数底层都封装了系统调用execve,只是产生了多种形式使得传参和功能更加多样化。

总结

        本篇文章,我们学习了进程控制的概念及进程创建、进程终止、进程等待和进程程序替换的相关Linux常用接口,学习了这些接口,想必大家能够更好地理解和掌握Linux系统中的进程控制技术。当然,进程控制还包括进程间通信,但这部分的知识涉及文件IO相关的内容,后续博主会给大家详细讲解。接下来博主会和大家一起,结合这些接口的使用方法及进程控制思想,写一个简单的Shell命令行程序。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

相关文章:

【Linux】进程控制

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、什么是进程控制 二、进程创建 三、进程终止&#xff08;进程退出&#xff09; 退出码 main函数返回 _exit() exit() 测试 四、进…...

设计模式-基础概念学习总结(继承、多态、虚方法、方法重写)

概念使用例子的方式介绍&#xff08;继承&#xff0c;多态&#xff0c;虚方法&#xff0c;方法重写&#xff09;&#xff0c;实现代码python 1. 继承&#xff08;Inheritance&#xff09; 概念&#xff1a;子类继承父类的属性和方法&#xff0c;可以直接复用父类的代码&#…...

分析rand()和srand()函数的功能

rand()和srand()函数原型&#xff1a; int rand(void) 返回一个范围在 0 到 RAND_MAX 之间的伪随机数。 void srand(unsigned int seed)用来给rand() 设置随机数发生器&#xff0c;随机数发生器输出不同的数值&#xff0c;rand() 就会生成不同的随机数 1)、在“D:\Keil_v5\AR…...

架构师如何构建个人IP:职业规划与业务战略的双重提升

在数字化时代&#xff0c;软件架构师的角色已从单纯的技术专家转变为兼具技术领导力和业务影响力的复合型人才。如何构建个人IP&#xff0c;提升行业影响力&#xff0c;成为架构师职业发展的关键课题。本文从个人认知、业务战略、架构决策、产品思维四个维度&#xff0c;探讨架…...

CSS知识总结

一、CSS核心概念解析 1.1 选择器体系&#xff08;重点&#xff09; 基础选择器&#xff1a; /* ID选择器 */ #header { background: #333; }/* 类选择器 */ .btn-primary { color: white; }/* 属性选择器 */ input[type"text"] { border: 1px solid #ccc; } 组合…...

CRS 16 slot 设备硬件架构

目录 1. 核心组件 1.1 线路卡与物理接口模块 1.2 交换结构与容量 1.3 控制与管理 1.4 风扇与散热 1.5 电源与告警 2. 插槽编号与机箱布局 2.1 前侧&#xff08;PLIM 面&#xff09; 2.2 后侧&#xff08;MSC 面&#xff09; 2.3 插槽配对 1. 核心组件 1.1 线路卡与物…...

人工智能浪潮中Python的核心作用与重要地位

在人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;蓬勃发展的时代&#xff0c;Python已然成为推动这一技术进步的关键编程语言。从复杂的机器学习算法实现&#xff0c;到前沿的深度学习模型构建&#xff0c;再到智能系统的部署&#xff0c;Python无处不…...

【了解】数字孪生网络(Digital Twin Network,DTN)

目录 一、为什么&#xff1f;二、是什么&#xff1f;三、什么架构&#xff1f;四、如何应用&#xff1f;参考 一、为什么&#xff1f; 一方面&#xff0c;网络负载不断增加,&#xff0c;网络规模持续扩大带来的网络复杂性&#xff0c;使得网络的运行和维护变得越来越复杂。另一…...

[C语言]第一章-初识

目录 一.引言 二.MinGW 下载与安装 1.什么是 MinGW 2.下载 MinGW 3.安装 MinGW 4.配置 MinGW 环境变量 三.VS Code 下载与安装 1.什么是 VS Code 2.下载 VS Code 3.安装 VS Code 4.汉化 5.安装扩展插件 C/C 截图 四.编写并运行 Hello World 程序 代码解释 运行…...

如何用git将项目上传到github

步骤 1.创建仓库 2.记下仓库的url 3.在本地初始化仓库 路径要在项目下 cd /path/to/your/vue-project git init 4.创建touch .gitignore文件 在项目根目录下创建 .gitignore 文件&#xff0c;用于指定 Git 忽略哪些文件或文件夹 5.添加和提交项目文件 将文件提交到版本控…...

C++入门(上)--《Hello C++ World!》(1)(C/C++)

文章目录 前言命名空间域命名空间的用法 C的输入和输出缺省参数函数重载auto关键字(C11)范围for 前言 C不是C# C兼容大部分C的东西&#xff0c;但不是完全(98%的样子&#xff0c;除非遇到了不兼容的&#xff0c;那就记一下&#xff0c;不然就认为自己在C里面写的那些可以写到C里…...

架构思维:构建高并发读服务_基于流量回放实现读服务的自动化测试回归方案

文章目录 引言一、升级读服务架构&#xff0c;为什么需要自动化测试&#xff1f;二、自动化回归测试系统&#xff1a;整体架构概览三、日志收集1. 拦截方式2. 存储与优化策略3. 架构进化 四、数据回放技术实现关键能力 五、差异对比对比方式灵活配置 六、三种回放模式详解1. 离…...

代码随想录第33天:动态规划6(完全背包基础)

一、完全平方数&#xff08;Leetcode 279&#xff09; 本题与“零钱兑换”基本一致。 1.确定dp数组以及下标的含义 dp[j]&#xff1a;和为j的完全平方数的最少数量为dp[j] 2.确定递推公式 dp[j] 可以由dp[j - i * i]推出&#xff0c; dp[j - i * i] 1 便可以凑成dp[j]。 …...

Android控件View、ImageView、WebView用法

一 控件清单 View、ImageView、WebView 二 控件UI代码 <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app=&qu…...

关于浏览器页面自动化操作

Selenium 是一个用于自动化浏览器操作的强大框架&#xff0c;广泛应用于Web应用程序的测试自动化。它主要由以下几个核心组件组成&#xff1a; Selenium WebDriver&#xff1a; WebDriver 是 Selenium 的核心组件&#xff0c;它提供了一组API&#xff0c;允许开发者编写程序来…...

P5739 计算阶乘详解

此题目&#xff0c;对于会递归的很简单很简单&#xff0c;但作者是野人不会&#xff0c;只能是边刷边学&#xff0c;且题解比较有意思&#xff0c;所有我这次的重心不是题目&#xff0c;而是题解里面创作者展示的不一样的东西&#xff0c;先看题目 题目要求不用for循环&#xf…...

把Android设备变成“国标摄像头”:GB28181移动终端实战接入指南

把Android设备变成“国标摄像头”&#xff1a;GB28181移动终端实战接入指南 ——执法记录仪、巡检终端、布控球&#xff0c;如何通过大牛直播SDK直接挂到GB28181平台&#xff1f; 在过去&#xff0c;GB28181 通常用于固定摄像头、NVR等“设备端”。但在政务、安防、应急等行业…...

机器学习项目流程极简入门:从数据到部署的完整指南

前言 本文将通过一个简单案例&#xff08;根据水果外观特征判断是否为橘子&#xff09;&#xff0c;逐步拆解机器学习项目的完整流程&#xff0c;帮助读者掌握从数据收集到模型部署的全流程方法论。 通常&#xff0c;一个完整的机器学习项目可以分为以下几个步骤&#xff1a; …...

PrivKV: Key-Value Data Collection with Local Differential Privacy论文阅读

文献阅读课需要制作ppt但是感觉选的这篇论文都是公式&#xff0c;决定做点动画直观展示一下。还没有完成会继续更新这个笔记 manim动画代码 需要下载ffmpeg下载latex https://docs.manim.org.cn/getting_started/installation.html ffmpeg下载教程 texlive官网 但是其实不需要…...

RViz(机器人可视化工具)的配置文件(moveitcpp)

1. Panels&#xff08;面板设置&#xff09; 面板是RViz界面中的各个功能区域&#xff0c;用于显示和操作不同的数据。 Displays&#xff08;显示面板&#xff09; Class: rviz_common/Displays 指定面板的类型&#xff0c;这里是显示面板。 Help Height: 78 帮助区域的高度…...

kotlin 01flow-StateFlow 完整教程

一 Android StateFlow 完整教程&#xff1a;从入门到实战 StateFlow 是 Kotlin 协程库中用于状态管理的响应式流&#xff0c;特别适合在 Android 应用开发中管理 UI 状态。本教程将带全面了解 StateFlow 的使用方法。 1. StateFlow 基础概念 1.1 什么是 StateFlow? StateF…...

OpenGl实战笔记(1)基于qt5.15.2+mingw64+opengl绘制三角形

一、实现效果 二、实现原理 &#xff08;1&#xff09;各函数作用与原理 initialize() 作用&#xff1a; 初始化 OpenGL 函数&#xff08;initializeOpenGLFunctions()&#xff09; 设置背景清除颜色为 rgba(0.2, 0.3, 0.4, 1.0)。 原理&#xff1a; initializeOpenGLFunctio…...

S100平台调试RS485/RS232

提供一个C语言的测试程序Demo #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>...

蓝桥杯 19. 植树

植树 题目描述 小明和朋友们一起去郊外植树&#xff0c;他们带了一些在实验室中精心研究出的小树苗。 一共有 n 个人&#xff0c;每个人挑选了一个适合植树的位置&#xff0c;一共 n 个位置。每人准备在自己的位置种下一棵树苗。 但他们遇到一个问题&#xff1a;有的树苗比…...

Spring Boot 中 @Bean 注解详解:从入门到实践

在 Spring Boot 开发中&#xff0c;Bean注解是一个非常重要且常用的注解&#xff0c;它能够帮助开发者轻松地将 Java 对象纳入 Spring 容器的管理之下&#xff0c;实现对象的依赖注入和生命周期管理。对于新手来说&#xff0c;理解并掌握Bean注解&#xff0c;是深入学习 Spring…...

git项目迁移,包括所有的提交记录和分支 gitlab迁移到gitblit

之前git都是全新项目上传&#xff0c;没有迁移过&#xff0c;因为迁移的话要考虑已有项目上的分支都要迁移过去&#xff0c;提交记录能迁移就好&#xff1b;分支如果按照全新项目上传的方式需要新git手动创建好老git已有分支&#xff0c;在手动一个一个克隆老项目分支代码依次提…...

前端面试每日三题 - Day 25

这是我为准备前端/全栈开发工程师面试整理的第25天每日三题练习&#xff0c;涵盖了&#xff1a; CSS中如何实现一个保持宽高比的自适应正方形元素Angular的变更检测&#xff08;Change Detection&#xff09;机制项目实战 - 设计一个微前端架构的前端应用。 ✅ 题目1&#xff…...

基于windows安装MySQL8.0.40

基于windows安装MySQL8.0.40 基于windows 安装 MySQL8.0.40&#xff0c;解压文件到D:\mysql-8.0.40-winx64 在D:\mysql-8.0.40-winx64目录下创建my.ini文件&#xff0c;并更新一下内容 [client] #客户端设置&#xff0c;即客户端默认的连接参数 # 设置mysql客户端连接服务…...

基于机器学习算法预测二手车市场数据清洗与分析平台(源码+定制+讲解) 基于Python的数据挖掘与可视化 二手车数据处理与分析系统开发 (机器学习算法预测)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

【神经网络与深度学习】普通自编码器和变分自编码器的区别

引言 自编码器&#xff08;Autoencoder&#xff0c;AE&#xff09;和变分自编码器&#xff08;Variational Autoencoder&#xff0c;VAE&#xff09;是深度学习中广泛应用的两类神经网络结构&#xff0c;主要用于数据的压缩、重构和生成。然而&#xff0c;二者在模型设计、训练…...

【现代深度学习技术】现代循环神经网络07:序列到序列学习(seq2seq)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…...

【Linux我做主】进度条小程序深度解析

Linux下C语言进度条程序深度解析 进度条小程序GitHub地址 前言前置知识回车换行&#xff08;CR/LF&#xff09;的深度解析历史渊源与技术规范在进度条/倒计时中的应用 缓冲区机制的全面剖析缓冲区引入缓冲类型对比进度条开发中的关键控制 进度条实现以小见大——倒计时倒计时最…...

Vue项目安全实践指南:从输入验证到状态管理的全方位防护

一、项目背景 在Vue2项目开发过程中&#xff0c;我们遇到了一些需要优化的安全实践问题。本文将分享我们在项目中的一些安全优化经验&#xff0c;希望能帮助到其他开发者。 主要优化点&#xff1a; 输入输出安全处理请求安全防护数据存储安全路由访问控制文件上传处理表单数…...

Pinocchio导入URDF关节为continuous的问题及详细解释

视频讲解&#xff1a; Pinocchio导入URDF关节为continuous的问题及详细解释 仓库地址&#xff1a;GitHub - LitchiCheng/mujoco-learning 问题背景&#xff1a;打算测试将之前的panda的urdf换成so-arm100的urdf&#xff0c;发现pinocchio的代码不能用&#xff0c;很奇怪&#…...

《Python星球日记》第30天:Flask数据库集成

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏&#xff1a;《Python星球日记》&#xff0c;限时特价订阅中ing 目录 一、数据库…...

GAF-CNN-SSA-LSSVM故障诊断/分类预测,附带模型研究报告(Matlab)

GAF-CNN-SSA-LSSVM故障诊断/分类预测&#xff0c;附带模型研究报告&#xff08;Matlab&#xff09; 目录 GAF-CNN-SSA-LSSVM故障诊断/分类预测&#xff0c;附带模型研究报告&#xff08;Matlab&#xff09;效果一览基本描述程序设计参考资料 效果一览 基本描述 本研究提出的GA…...

轻松养生:让健康融入生活

养生不是负担&#xff0c;而是可以轻松融入日常的生活方式。掌握以下要点&#xff0c;就能开启健康之旅。 清晨醒来&#xff0c;先喝一杯常温水&#xff0c;唤醒沉睡的肠胃。早餐选择富含膳食纤维的燕麦片搭配新鲜水果&#xff0c;补充能量又促进消化。午餐和晚餐做到荤素搭配&…...

工业主义与民主的兴衰:历史逻辑与未来危机

一、工业主义催生大众民主的机制 经济基础变革 非技术工人崛起&#xff1a;工业革命后&#xff0c;机器生产替代传统手工业&#xff0c;非熟练工人&#xff08;包括妇女、儿童&#xff09;收入提升&#xff0c;财富分配趋于平等&#xff0c;形成新兴中产阶级。 政府财政能力增…...

从代码学习深度学习 - 目标检测前置知识(二) PyTorch版

文章目录 前言一、多尺度目标检测1.1 多尺度锚框1.2 绘图工具函数 (`utils_for_huitu.py`)1.3 可视化多尺度锚框1.4 多尺度检测(理论)二、自定义目标检测数据集2.1 读取数据2.2 创建 Dataset 类2.3 创建 DataLoader2.4 验证数据加载2.5 可视化数据集样本总结前言 大家好!欢…...

什么是“系统调用”

一、什么是“系统调用”&#xff1f;用生活中的比喻理解 可以把“系统调用”比作你&#xff08;用户&#xff09;向“管理员”请求帮助完成某件事情的过程。 举个例子&#xff1a; 你想借书&#xff0c;去图书馆&#xff08;操作系统&#xff09;找管理员&#xff08;内核&a…...

代码异味(Code Smell)识别与重构指南

1、引言:什么是“代码异味”? 在软件开发中,“代码异味(Code Smell)”是指那些虽然不会导致程序编译失败或运行错误,但暗示着潜在设计缺陷或可维护性问题的代码结构。它们是代码演进过程中的“信号灯”,提示我们某段代码可能需要优化。 1.1 ✅ 为什么关注代码异味? 预…...

005-nlohmann/json 基础方法-C++开源库108杰

《二、基础方法》&#xff1a;节点访问、值获取、显式 vs 隐式、异常处理、迭代器、类型检测、异常处理……一节课搞定C处理JSON数据85%的需求…… JSON 字段的简单类型包括&#xff1a;number、boolean、string 和 null&#xff08;即空值&#xff09;&#xff1b;复杂类型则有…...

java学习之数据结构:四、树(代码补充)

这部分主要是用代码实现有序二叉树、树遍历、删除节点 目录 1.构建有序二叉树 1.1原理 1.2插入实现 2.广度优先遍历--队列实现 3.深度优先遍历--递归实现 3.1先序遍历 3.2中序遍历 3.3后序遍历 4.删除 4.1删除叶子节点 4.2删除有一棵子树的节点 4.3删除有两棵子树的节…...

Java面试场景分析:从音视频到安全与风控的技术探讨

Java面试场景分析&#xff1a;从音视频到安全与风控的技术探讨 在一个阳光明媚的早晨&#xff0c;互联网大厂的面试室里&#xff0c;面试官李老师坐在桌前&#xff0c;严肃认真&#xff1b;而程序员小张则显得有些紧张&#xff0c;甚至有些搞笑。 第一轮提问&#xff1a; 李老…...

《OmniMeetProTrack 全维会议链智能追录系统 软件设计文档》

撰稿人&#xff1a;wjz 一、引言 1.1 目的 本软件设计文档详细描述了 OmniMeetProTrack 全维会议链智能追录系统的架构、组件、模块设计及实现细节&#xff0c;旨在为开发人员、利益相关者和维护人员提供系统的全面设计蓝图。本文档基于需求定义文档&#xff0c;确保系统实现…...

C 语言逻辑运算符:组合判断,构建更复杂的条件

各类资料学习下载合集 ​​https://pan.quark.cn/s/8c91ccb5a474​​ 在 C 语言编程中,我们已经学习了如何使用比较运算符(如 ​​==​​​, ​​<​​​, ​​>​​)来判断两个值之间的关系,从而得到“真”或“假”的结果。但很多时候,我们需要根据多个条件的组合…...

大模型推理框架简介

概述 通常需要大量的计算资源&#xff0c;高效运行LLMs仍然是一个挑战&#xff0c; 推理框架作为LLM高效部署的关键组件&#xff0c;直接关系到应用的性能、成本和开发效率。 高性能框架 vLLM GitHub&#xff0c;由SKYPILOT构建的推理优化框架&#xff0c;旨在提高在GPU上…...

《MATLAB实战训练营:从入门到工业级应用》高阶挑战篇-《5G通信速成:MATLAB毫米波信道建模仿真指南》

《MATLAB实战训练营&#xff1a;从入门到工业级应用》高阶挑战篇-5G通信速成&#xff1a;MATLAB毫米波信道建模仿真指南 &#x1f680;&#x1f4e1; 大家好&#xff01;今天我将带大家进入5G通信的奇妙世界&#xff0c;我们一起探索5G通信中最激动人心的部分之一——毫米波信…...

word导出pdf带有目录导航栏-error记

1、打开word文档——>点击"视图"选项卡——>勾选"导航窗格" 2、点击"文件"——>导出——>创建PDF/XPS 3、点击"选项"——>勾选"创建书签时使用(C)" "标题(H)" 4、点击"确定"——>点击…...

word怎么删除空白页?word最后一页删不掉怎么办

在使用word的过程中&#xff0c;有时出现空白页就可能会给大家带来一些困扰。到底怎么样才能把这些空白页删除&#xff0c;又应该如何解决最后也删不掉的问题呢&#xff1f; 要想删除普通的空白页&#xff0c;那就需要将光标直接放在空白页&#xff0c;然后按【Delete】键&…...