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

【Linux】进程基础入门指南(下)

 > 🍃 本系列为Linux的内容,如果感兴趣,欢迎订阅🚩

> 🎊个人主页:【小编的个人主页

>小编将在这里分享学习Linux的心路历程✨和知识分享🔍

>如果本篇文章有不足,还请多多包涵!🙏
>  🎀   🎉欢迎大家点赞👍收藏⭐文章

> ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍


目录

🐼前言  

🐼进程属性

🐼查看进程

🐼通过系统调用创建进程

🐼创建多个进程   

🐼总结


🐼前言  

在上一节,我们知道管理的本质,为什么有系统调用,以及操作系统是如何管理进程的:就是先描述,再组织。这一节,我们进一步来探寻进程,看看这个进程(学生)有哪些属性(需要我们后续继续学习),以及如何查看一个进程,创建一个进程,话不多说,直接开冲!


🐼进程属性

在Linux描述进程的结构体是task_struct,我们先粗略认识一下进程有哪些属性,先搭建个框架出来,感性的认识一下进程属性:

1️⃣ 标识符:描述本进程的 唯一 标识符,用来区别其他进程。( 就好比每个学生的学号是唯一的 ,我能通过这个学号来快速定位这个学生是谁,因此,在进程中,也要有一个标识符, 一般是一个数字(无符号整数)来标识进程的唯一性 ,如何查看标识符,我们在下面会提及)
2️⃣ 状态: 任务状态,退出代码,退出信号等。(这就好比我们每个学生在学校的一天,有学习的状态,吃饭的状态,睡觉的状态...)我们下一节会具体认识一下进程状态
3️⃣ 优先级: 相对于其他进程的优先级。(这就好比我们在食堂排队时的优先级,排在前面的先打到饭,排后面的后打到饭,所以进程优先级也是一个道理)
4️⃣ 程序计数器: 程序中即将被执行的下一条指令的地址。
这个该怎么理解呢?我们在之前学习写的C/C++代码时,是如何完成函数跳转,循环语句,条件判断呢?都是PC指针的功劳,PC(point count)指针会告诉CPU要执行的下一条语句, 他就像个"诸葛亮" ,将要执行的下一条语句的地址提前保存起来。为什么是这样的呢???为什么需要PC指针??
其实,CPU没有我们想象的那么那么"聪明",它反而是很笨的!在CPU中,有一个IR(instruction register)寄存器,它喂给CPU什么,CPU吃什么。CPU没有自已的想法。而IR寄存器和PC寄存器配合一下,也就是 ,PC指针先想法设法提前拿到下一条指令的地址,然后IR将当前语句喂给CPU,PC指针再把值赋给IR,再执行。 也就是下图:
因此我们可以理解了,调试中,程序是如何跳转的!!!
5️⃣ 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。( 粗略理解成能找到PCB代码的内存数据的 )
上下文数据: 进程执行时处理器的寄存器中的数据。这个怎么理解呢?由于CPU只有一个,而进程是有多个的,那么这些进程都会抢着来用CPU的资源,但是有的进程是不合理的,比如,我们程序写的死循环,那么不可能我一个进程一直占用CPU资源,所以,CPU会对进程分配时间。也就是 CPU不会将一个程序全部执行完才切换到下一个进程,而是在中途可能就会发生进程切换!
那么切换进程之前,需要提前保存CPU中进行我这个进程的硬件碎片信息到PCB中,以方便一下次执行我时不用重新执行,而是根据上一次未执行完的步骤继续执行。目的就是为了方便硬件上下文的保护和恢复!不需要再重新执行,感性的理解为无缝衔接了!
6️⃣ 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。(也就是为了关于进程的公平公正调度,避免一个进程一直占着资源,其他新进程得不到CPU资源)
.......其他的task_struct中的属性我们后续慢慢学习,我们这里也是粗略认识一些进程属性。

🐼查看进程

我们创建一个程序,通过getpid获取该进程的唯一标识符:

通过man手册,我们看看getpid。即返回当前进程的标识符.本质上是通过系统调用的方式来获取PCB中的pid

int main()
{while(1){printf("我是一个进程,pid:%d\n",getpid());sleep(1);}return 0;
}

让我们的进程跑起来:

查看进程:

方式1:

我们根目录下有一个proc的文件,我们可以通过

ls /proc 查看proc目录下的所有进程(系统会给每一个正在运行的进程创建一个文件)

我们找一找我们的进程存在不?

确实存在!!!当我们停止该进程(crtl+c),proc下的就会对该进程的文件信息释放了!再查找就找不到了。这就证明了当我们的进程在运行时,系统会自动在/proc目录下创建一个名为该进程编号pid的文件,当我们停止该进程,该文件释放 

我们发现每次创建该进程的pid名都不一样,因此系统中同时有大量的进程,所以是不确定的


我们观察上图,该进程的详细信息中有个cwd的,也就是该进程的当前路径,默认每个进程的当前路径是创建当前可执行程序的路径,也就是myprocess的路径

也就是当前路径是默认在该目录下,因此我们可以修改改进程的当前路径!

比如创建文件时,我们可以通过修改当前路径了改变我们创建的文件路径


方式2:上述查看进程方式不常用

我们经常使用 ps axj 来查看所有进程再用grep过滤我们的进程

因此常用: ps axj | grep "可执行程序名" 

为了看到头部信息:

ps axj  |  head -1 ; ps axj  |  grep "可执行程序名" 或者ps axj  |  head -1 && ps axj  |  grep "可执行程序名"

最终,我们经常使用上述方式来查看进程:

那gerp是什么鬼,我们不只查看myprocess这个进程吗,和他有什么关系,它为什么会出来???

其实,不管是我们的命令ls 还是pwd 还是 cd,我们之前就知道,它都是一个可执行的二进制程序,因此他也是一个进程,当我们输入ls,它作为一个进程会被加载到内存被CPU进行调度执行。因此这里grep也是一个命令,当然是进程,也要被CPU执行,因此我们看到grep的进程。

那还有一个pts文件是干嘛呢,其实,粗略的讲它就是关联该进程的显示屏文件,因此我们也通过pts显示屏文件向该目标进程的显示器输出:

比如这样:


其中我们知道pid是该进程编号,那么ppid呢,就是该进程的父进程编号

getppid()来获取父进程编号!本质上是通过系统调用的方式来获取PCB中的ppid(父进程编号)

在Linux中,创建进程,是通过父进程增加子进程的方式来创建的,让进程的个数变多的

为了更清楚的演示,我们将代码改一下,将父进程ppid也打印出来:

我们发现,子进程一直在变,可是父进程怎么始终不变?????它究竟是谁??

它是bash!!!

在我们Linux中,启动命令/程序的时候,都会变成进程,他们都是由bash这个父进程来创建的~


🐼通过系统调用创建进程

我们已经了解到,我们通过命令行启动的可执行程序的进程是由bash创建的。那么,bash又是如何创建的呢?

我们知道,进程本质上是内核数据结构(task_struct)加上代码和数据。创建一个进程,实际上就是创建一个新的task_struct以及其对应的代码和数据。而创建子进程的核心机制是通过系统调用fork实现的。

换句话说,我们在命令行启动的命令或可执行程序是一个子进程,它是bash通过fork系统调用创建的。具体来说,bash在底层调用了fork,从而生成了一个新的子进程。这个子进程继承了父进程(bash)的大部分资源,包括代码和数据空间,并在此基础上运行我们指定的程序。

下面我们来创建一个进程:

int main()
{printf("我是一个进程,pid:%d 父进程:%d\n",getpid(),getppid());sleep(1);fork();printf("你猜我被执行了吗???\n");sleep(1);return 0;}

输出: 

printf被执行了两次????

这是因为 fork() 后,父进程创建了一个子进程,子进程是父进程的副本。fork()调用之后,代码会在父进程和子进程中分别继续执行,因此 printf 在父进程中执行一次,在子进程中也执行一次,总共被执行两次。换句话说,fork() 之后,两个进程是分开独立运行的!

我们可以得出一个结论,父子进程是互相独立,互不影响的!!

那我们观察一下他们的pid和ppid

确实在fork之后有两个进程,第二个进程以第一个进程为副本。第二个进程是第一个进程的子进程,第一个进程是第二个进程的父进程。第一个进程的父进程是bash!


我们再来看一下fork的返回值:

man手册告诉我们,fork()的返回值:如果子进程创建成功,父进程会返回子进程的pid,子进程返回0;创建失败,则会父进程返回-1,子进程没有被创建。

什么鬼,一个函数还能有两个返回值???

int main()
{printf("我是一个进程,pid:%d 父进程:%d\n",getpid(),getppid());sleep(1);pid_t id = fork();printf("你猜我被执行了吗???pid:%d ppid:%d id:%d\n",getpid(),getppid(),id);sleep(1);return 0;}

我们测试一下:

啊,确实如man手册所说,父进程会返回子进程的pid,子进程返回0;

为什么返回值是这样的?父进程返回pid,子进程返回0???

因为一个父进程可能会创建多个子进程,他们是1:n的关系,因此一个父进程要保存子进程的唯一标识符,以至于能找到子进程。子进程返回0说明创建成功了。

那fork()之后有两个返回值能做什么???

fork()后有两个返回值(父进程中返回子进程的PID,子进程中返回0)的原因是为了区分父子进程,并允许在fork()调用之后分别编写不同的逻辑。使得父子进程可以独立运行,同时父进程可以对子进程进行管理。也就是让父子进程分别执行不同的代码区域,从而让父子执行不同的任务!!!

因此我们代码逻辑可以这样写,让父子进程分别执行不同的代码区域:

#include<stdio.h>
#include<unistd.h>int main()
{//pid_t id = getpid();//pid_t ppid = getppid();printf("我是一个进程,pid:%d ppid:%d\n",getpid(),getppid());sleep(1);int id = fork();if(id<0){perror("fork fail!");return 1;}else if(id ==0){while(1){printf("我是子进程 pid:%d  ppid:%d  id:%d\n",getpid(),getppid(),id);sleep(1);}}else{while(1){printf("我是父进程 pid:%d  ppid:%d  id:%d\n",getpid(),getppid(),id);sleep(2);}}sleep(1);return 0;
}

输出:

确实创建父进程创建出了子进程

我们发现,else if else 两条语句都执行了,这在我们之前学习的C/C++是根本不可能做到的。正是由于fork后,父子,由于fork返回值的不同,让父子代码区域独立了,父子分别执行不同的任务!我们才看到了上述现象。 

那fork之后为什么有两个返回值???因为我们仅仅调用的fork()是系统调用,而在fork()里面,待我们执行到return 的时候,已经完成了父进程创建子进程的工作,主体工作已经做完了!!!(给我们"暗箱操作"了)因此在return 之前,已经完成了分支,有两个返回值就不奇怪了(具体怎么做到的,我们需要在后续虚拟地址空间再回来解释一下!)

那父进程如何创建子进程的,子进程被创建时,内部什么都没有吗?

在上述的例子中,我们已经或许知道答案了,比如子进程也会执行printf语句。在Linux中子进程在被创建时,也会被初始化,而怎么初始化,就是以父进程为模版。并且,子进程的代码和数据时默认共享父进程的代码和数据,在之后在对子进程的代码和数据进行修改。而为了保证数据层面的独立性,如果子进程数据要修改,用写实拷贝!!!


🐼创建多个进程   

下面,我们一次性来创建10个进程:

#include<stdio.h>
#include<unistd.h>const int N = 10;
int main()
{for(int i=0;i<N;i++){pid_t id = fork();if(id == 0){//子while(1){printf("我是子进程 pid:%d ppid:%d\n",getpid(),getppid());sleep(1);}}else{//父,什么都不做---父进程要创建子进程printf("子进程创建成功 pid%d\n",getpid());sleep(1);}}//父进程被创建while(1){printf("父进程创建成功 pid:%d ppid:%d\n",getpid(),getppid());sleep(1);}return 0;
}

该程序创建流程图:

确实一次性由myfork这个父进程创建了10个子进程,myfork的的父进程是bash!

我们也可以得出一个结论,父进程创建子进程的过程,父子进程,谁先执行不确定,由OS调度机制来决定


🐼总结

我们知道想要管理好进程,首先要先描述,因此我们粗略认识了进程属性,比如说标识符,程序计数器等,我们可以通过getppid(),getpid()来获取父子进程的唯一标识符。学会了用ps axj  |  head -1 ; ps axj  |  grep "可执行程序名"来查看系统的进程,也能通过开发者给我们的系统调用接口fork()来创建子进程,我们也知道了在Linux中,一切进程都是由父进程创建的,我们也能一次性创建多个进程。在下一篇文章,我们继续描述进程属性:进程状态!

相关文章:

【Linux】进程基础入门指南(下)

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有不足&#xff0c;还请多多包涵&a…...

NoETL×大模型:Aloudata重构数据智能新范式,开启Chat BI新落地之道

在当今数据驱动的时代&#xff0c;企业对于高效、智能的数据处理与分析需求日益增长。随着大模型的兴起&#xff0c;如DeepSeek等&#xff0c;数据智能领域正经历着前所未有的变革。 Aloudata大应科技创始人&CEO周卫林表示&#xff0c;企业的核心竞争力包括人才壁垒、技术…...

算法题(126):前缀和

审题&#xff1a; 本题需要我们将题目给出的数组的数据的[l,r]范围内的数据和打印 思路&#xff1a; 方法一&#xff1a;前缀和 前缀和的思想就是预处理数据&#xff0c;通过空间换时间的方式提高代码效率 第一步&#xff1a;利用数组f将前缀和记录下来&#xff0c;f[i]表示索引…...

选择排序(简单选择排序、堆排序)

简单选择排序&#xff08;Selection Sort&#xff09; 1. 算法思想 它通过多次遍历数组&#xff0c;每次从未排序部分中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;将其放到已排序部分的末尾&#xff08;或开头&#xff09;&#xff0c;直到整个数组有序。 2.…...

【JavaEE】Spring AOP的注解实现

目录 一、AOP 与 Spring AOP二、Spring AOP简单实现三、详解Spring AOP3.1 Spring AOP 核心概念3.1.1 切点&#xff08;Pointcut&#xff09;3.1.2 连接点&#xff08;Join Point&#xff09;3.1.3 通知&#xff08;Advice&#xff09;3.1.4 切面&#xff08;Aspect&#xff09…...

【天外之物】加速度与速度的单位向量的内积得到加速度在切向向量上的值

切向加速度的标量值 a T a_T aT​ 正是加速度矢量 a \mathbf{a} a 与单位切矢量 T ^ \mathbf{\hat{T}} T^ 的内积&#xff08;点积&#xff09;。 1. 数学定义 设物体的速度为 v \mathbf{v} v&#xff0c;加速度为 a \mathbf{a} a&#xff0c;单位切矢量为 T ^ \mathbf{…...

​​eBay 2025春季财报揭示跨境电商新蓝海:五大隐秘品类引爆增长密码​

核心数据速览​​ 2024年第一季度&#xff0c;eBay全球商品交易总额&#xff08;GMV&#xff09;达255亿美元&#xff0c;同比增长5%。这一增长不仅源于季节性消费回暖&#xff0c;更折射出跨境电商行业在能源转型、供应链重构及消费需求升级中的结构性变革。透过数据&#xff…...

兔子桌面tv版下载-兔子桌面tv版官方app免费下载安装

兔子桌面 TV 版是一款专为智能电视和机顶盒设计的轻量化桌面应用&#xff0c;其界面采用大图标、大字体设计&#xff0c;支持自由调整应用顺序&#xff0c;将常用的影视、游戏 App 置顶&#xff0c;还可通过主题市场下载动态背景&#xff0c;满足用户对电视界面的个性化需求。 …...

绿算轻舟系列FPGA加速卡:驱动数字化转型的核心动力【2】

工业与医疗&#xff1a;精准化的幕后推手 在工业4.0与智慧医疗领域&#xff0c;绿算轻舟FPGA加速卡通过实时信号处理与高精度控制&#xff0c;推动关键场景的技术升级。 工业自动化&#xff1a;在机器视觉质检中&#xff0c;实现亚像素级缺陷检测&#xff0c;产线检测速度大幅…...

ubuntu1804服务器开启ftp,局域网共享特定文件给匿名用户

要在 Ubuntu 18.04 上设置一个 FTP 服务器&#xff0c;满足以下要求&#xff1a; 允许匿名登录&#xff08;无需账号密码&#xff09;。指定分享特定目录下的文件。只允许只读下载。 可以使用 vsftpd&#xff08;Very Secure FTP Daemon&#xff09;来实现。以下是详细步骤&a…...

k8s中pod报错 FailedCreatePodSandBox

问题现象&#xff1a; 创建容器时出现一下情况 而且删掉控制器的时候pod还会卡住 解决&#xff1a; 将calico的pod重新删掉。其中有1个控制器pod以及3个node pod 删掉后&#xff0c;大概10来秒就重新创建完成了。 然后现在在使用kubectl apply -f 文件.yaml 就可以正常创…...

请详细说明下面训练阶段的差别: Supervised Fine-Tuning、Reward Modeling、PPO、DPO、KTO、Pre-Training

目录 &#x1f527; 一、训练阶段总体流程&#xff08;从底层到上层&#xff09; &#x1f9e0; 1. Pre-Training&#xff08;预训练&#xff09; &#x1f4cc; 目的&#xff1a; &#x1f4da; 数据&#xff1a; ⚙️ 方法&#xff1a; &#x1f4a1; 举个例子&#xf…...

Go语言入门到入土——一、安装和Hello World

Go语言入门到精通——安装和Hello World 文章目录 Go语言入门到精通——安装和Hello World下载并安装让Go跑起来为你的代码启动依赖跟踪调用外部包总结 下载并安装 下载地址&#xff1a;https://go.dev/dl/ 下载后傻瓜式安装 查看是否安装完成 go version让Go跑起来 创建一个…...

React 入门完全指南:从零开始构建现代 Web 应用

在当今快速发展的前端开发领域&#xff0c;React 凭借其高效的组件化架构和强大的生态系统&#xff0c;已成为最受欢迎的 JavaScript 库之一。根据 2023 年 Stack Overflow 开发者调查&#xff0c;React 连续七年成为最常用的 Web 框架。无论是初创公司还是科技巨头&#xff0c…...

0701表单组件-react-仿低代码平台项目

文章目录 1 react表单组件1.1 受控组件 (Controlled Components)示例代码&#xff1a; 1.2 非受控组件 (Uncontrolled Components)示例代码&#xff1a; 2 AntD表单组件实战2.1 开发搜索功能2.2 开发注册页2.3 开发登录页2.4 表单组件校验 结语 1 react表单组件 input表单组件…...

Android ViewStub显示VISIBLE与消失GONE,Kotlin(2)

Android ViewStub显示VISIBLE与消失GONE&#xff0c;Kotlin&#xff08;2&#xff09; 在 Android ViewStub显示VISIBLE与消失GONE&#xff0c;Kotlin-CSDN博客 基础上完善。 import android.os.Bundle import android.util.Log import android.view.View import android.view…...

跨站脚本(XSS) 的详细分类、对比及解决方案

以下是 跨站脚本&#xff08;XSS&#xff09; 的详细分类、对比及解决方案&#xff1a; 一、XSS的分类与详解 1. 反射型XSS&#xff08;非持久型XSS&#xff09; 定义&#xff1a;攻击载荷通过URL参数传递&#xff0c;服务器直接返回到页面中&#xff0c;需用户主动触发。 工…...

JVM:程序计数器、虚拟机栈、本地方法栈

一、程序计数器 &#xff08;1&#xff09;程序计数器介绍 作用&#xff1a;当线程执行 Java 方法时&#xff0c;程序计数器记录该线程下一条要执行的字节码指令的地址&#xff1b;当线程执行本地方法时&#xff0c;程序计数器的值为未指定&#xff08;undefined&#xff09;…...

适配器模式在Java开发中的应用

适配器模式&#xff08;Adapter Pattern&#xff09;是设计模式中的一种结构型模式&#xff0c;它允许将一个类的接口转换成客户端所期望的另一个接口。通过这种方式&#xff0c;原本因接口不兼容而无法协同工作的类能够一起工作。适配器模式在Java开发中非常常见&#xff0c;尤…...

(三)谷歌Code as Policies复现(操作记录)

目录 《复现的项目来源》 一、创建虚拟环境 二、下载原项目并修改&#xff08;非必须&#xff09; 二、可直接下载修改后的项目 三、配置环境 &#xff08;1&#xff09;安装jupyterlab以及内核 &#xff08;2&#xff09;安装ffmpeg &#xff08;3&#xff09;配置环境…...

驱动学习专栏--字符设备驱动篇--2_字符设备注册与注销

对于字符设备驱动而言&#xff0c;当驱动模块加载成功以后需要注册字符设备&#xff0c;同样&#xff0c;卸载驱动模 块的时候也需要注销掉字符设备。字符设备的注册和注销函数原型如下所示 : static inline int register_chrdev(unsigned int major, const char *name, const…...

奥创中心卸载工具Armoury Crate Uninstall Tool官网下载

为了应对用户对 Armoury Crate 占用资源大、卸载困难等问题的普遍反馈&#xff0c;ASUS 官方提供了一个专门的卸载工具&#xff0c;即 Armoury Crate Uninstall Tool(奥创中心卸载工具)。该工具的主要作用是帮助用户彻底从系统中移除 Armoury Crate 相关的所有组件&#xff0c;…...

【Linux网络】网络基础概念深度解析

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

【NLP 61、大模型应用 —— RAG方法】

生活打不败一个大口吃饭的人&#xff01; —— 25.4.13 一、模型幻觉问题 模型幻觉&#xff08;AI Hallucination&#xff09;是指人工智能模型&#xff08;尤其是大语言模型&#xff09;生成看似合理但实际不准确、虚构或与事实不符内容的现象。其本质是模型基于统计概…...

UV工具——小试牛刀

背景 MCP开发使用到 为什么MCP更推荐使用uv进行环境管理&#xff1f; MCP 依赖的 Python 环境可能包含多个模块&#xff0c;uv 通过 pyproject.toml 提供更高效的管理方式&#xff0c;并且可以避免 pip 的一些依赖冲突问题。此外&#xff0c;uv 的包管理速度远超 pip…...

vue3+vite 多个环境配置

同一套代码 再也不用在不同的环境里来回切换请求地址了 然后踩了一个坑 就是env的文件路径是在当前项目下 不是在views内 因为公司项目需求只有dev和pro两个环境 虽然我新增了3个 但是只在这两个里面配置了 .env是可以配置一些公共配置的 目前需求来说不需要 所以我也懒得配了。…...

《分布式软总线架构下,设备虚拟化技术的深度剖析与优化策略》

设备之间的互联互通和协同工作已成为一种趋势。分布式软总线架构作为实现这一目标的关键技术&#xff0c;为不同设备之间的通信和协作提供了基础。而设备虚拟化技术则是在分布式软总线架构下&#xff0c;进一步提升设备资源利用效率的重要手段。本文将深入探讨在分布式软总线架…...

MCP 正当时:FunctionAI MCP 开发平台来了!

作者&#xff1a;封崇 MCP&#xff1a;AI 时代的“操作系统接口” 2024 年 11 月&#xff0c;Anthropic 发布模型上下文协议&#xff08;MCP&#xff09;&#xff0c;这一开放标准迅速引发开发者社区的"协议觉醒"。其本质是通过标准化接口实现 LLM 与外部世界的双向…...

AI Agents系列之AI代理的类型

在本文中,我们将探讨不同类型的 AI 代理,包括它们的实现、实际应用、优势和局限性。从简单反射代理到多代理系统,我们将了解这些模型如何推动自动化、决策制定和智能问题解决。 文章目录 1. AI代理的类型1.1 简单反射代理1.1.1 实现**1.1.2 优势****1.1.3 局限性**1.2 基于…...

Go RabbitMQ基础教程:入门与实践指南,实战代码讲解

简介&#xff1a; RabbitMQ是一款实现高级消息队列协议&#xff08;AMQP&#xff09;的消息代理软件&#xff0c;也称为消息队列或消息中间件。它通过解耦应用程序之间的直接通信&#xff0c;支持异步数据交换&#xff0c;增强了系统的可扩展性和灵活性。RabbitMQ能够跨平台运…...

LeetCode详解之如何一步步优化到最佳解法:27. 移除元素

LeetCode详解系列的总目录&#xff08;持续更新中&#xff09;&#xff1a; LeetCode详解之如何一步步优化到最佳解法&#xff1a;前100题目录&#xff08;更新中...&#xff09;-CSDN博客 LeetCode详解系列的上一题链接&#xff1a; LeetCode详解之如何一步步优化到最佳解法…...

c++原子操作

原子操作&#xff0c;顾名思义&#xff0c;该操作不可分割。多线程环境也能保证读写数据不错乱。百度搜索了下&#xff0c;其核心概念如下&#xff1a; 1、不可分割性。原子操作是指一系列不可被CPU上下文交换的机器指令&#xff0c;操作要么完全执行&#xff0c;要么完全不执…...

在 Redis Lua 脚本中,keyCount 参数的作用是明确区分脚本参数中的 KEYS 和 ARGV,具体关系如下:

在 Redis Lua 脚本中&#xff0c;keyCount 参数的作用是**明确区分脚本参数中的 KEYS 和 ARGV**&#xff0c;具体关系如下&#xff1a; --- ### 核心作用 1. **参数分类标识** - keyCount 表示脚本中使用的 Redis KEY 的数量&#xff08;即 KEYS 数组的长度&#xff09;…...

小白如何从0学习CSS

以下是针对小白从零开始系统学习 CSS 的完整路径和实用指南&#xff0c;结合核心概念、实践技巧和项目经验&#xff0c;助你掌握网页样式的精髓&#xff1a; 1. 理解 CSS 是什么&#xff1f; 定义&#xff1a;CSS&#xff08;层叠样式表&#xff09;用于控制网页的视觉表现&…...

一文掌握RK3568开发板Android13挂载Windows共享目录

在物联网和边缘计算场景中&#xff0c;开发板与PC端的高效文件交互尤为重要。现以iTOP-RK3568开发板为例&#xff0c;详细演示Android13系统如何通过CIFS协议挂载Windows共享目录&#xff0c;实现开发板与PC的无缝文件共享。 RK3568开发板优势 iTOP-3568开发板采用瑞芯微RK3…...

UE5烘培后->为什么C磁盘满了

烘培会产生ddc 需要把路径切换一下&#xff0c;比如切换到游戏空间下。 如何修改&#xff0c;修改如下&#xff1a; 使用记事本打开BaseEngine.ini文件。 将以下内容&#xff1a; textCopy Code Path\"%ENGINEVERSIONAGNOSTICUSERDIR%DerivedDataCache\" 替换为&…...

本地搭建全网可访问的开源音乐服务器Melody结合内网穿透随时听歌

文章目录 前言1. 添加镜像源2. 本地部署Melody3. 本地访问与使用演示4. 安装内网穿透5. 配置Melody公网地址6. 配置固定公网地址 前言 嗨&#xff0c;各位音乐发烧友们&#xff01;今天我要带你们解锁一个超酷的新技能——在香橙派Zero3上搭建自己的在线音乐平台&#xff0c;并…...

深度学习Y5周:yolo.py文件解读

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前言 文件位置&#xff1a;./models/yolo.py 此文件是实现YOLOv5网络模型的搭建文件&#xff0c;如果想改进YOLOv5&#xff0c;这个文件是必须进行修改的…...

Qt实现文件传输服务器端(图文详解+代码详细注释)

Qt实现文件传输服务器 1、前言2、服务器2.1 服务器UI界面2.2添加网络模块和头文件2.3、创建服务器对象2.4 连接有新连接的信号与槽2.5实现有新连接处理的槽函数2.6 选择文件按钮实现2.6.1 连接按钮点击的信号与槽2.6.2 添加头文件2.6.3 创建所需对象2.6.3 选择文件按钮实现 2.7…...

记录学习的第二十七天

今天效率低下&#xff0c;只做了一道力扣的每日一题。 看了题解才懂的。下面复述一遍吧。 算法就是越长越合法型滑动窗口。 核心&#xff1a; 如果此时窗口中有c个元素x&#xff0c;此时再进一个x&#xff0c;那么相同数对就增加c个。 如果此时窗口有c个元素x&#xff0c;此…...

docker 安装TDengine 时序数据库

TDengine是一个高性能、分布式a的时序数据库&#xff0c;专为物联网(loT)和大数据分析日设计。使用Docker快速地搭建 TDengine 的开发或测试环境。以下技术指南&#xff0c;帮助您通过Docker Compose 安装并运行TDengine 1.拉取镜像 (3.3.6.0版本) docker pull registry.cn-ha…...

如何更好使用呼叫中心系统和语音机器人

​要更好地使用呼叫中心系统和语音机器人&#xff0c;需要结合两者的优势&#xff0c;实现自动化、智能化、高效率的客户服务与业务运营。以下是优化策略和具体实践方法&#xff1a; 一、呼叫中心系统优化 1. 智能路由与IVR优化 ​ ​智能ACD&#xff08;自动呼叫分配&…...

C复习(主要复习)

指针和数组 指针数组是一个数组&#xff0c;数组的每个元素都是指针。它适用于需要存储多个指针的场景&#xff0c;如字符串数组。数组指针是一个指针&#xff0c;指向一个数组。它适用于需要传递整个数组给函数或处理多维数组的场景。 函数指针&#xff1a;函数指针的定义需要…...

网页五子棋项目测试报告

一、测试概述 网页五子棋项目运用 Java 语言与 Spring 框架开发&#xff0c;具备用户登录注册、人机对战、在线匹配对局、房间邀请对局及积分排行榜等功能。本次测试旨在评估项目各功能的完整性、稳定性与交互性&#xff0c;依据各文章所描述的功能设计和实现细节进行全面测试…...

大模型提示词prompt

系列文章目录 第一章 提示词的引言和指南 文章目录 系列文章目录前言原则1&#xff1a;写清楚具体的说明1、使用分割符2、要求结构化输出3、检查条件是否满足 检查完成任务所需的假设4、少量样例提示给出成功的例子 原则2&#xff1a;给模型足够的时间思考1、给予模型要输出执…...

如何让Agent开发正真可控、可靠?Cursor AI工程化

工程化的目的 不知道你在AI编程的过程中有没有这样的痛点&#xff1f;开发质量不理想、研发进度无法把控… 问题核心在于没有一套属于AI编程的规范&#xff0c;这正是工程化要解决的问题。 如何工程化 参考我们正常研发流程中的步骤&#xff0c;技术方案设计&评审->…...

计算机视觉——基于人工智能视觉注意力的在线广告中评估检测技术

概述 自2023年在线广告行业估计花费了7403亿美元以来&#xff0c;很容易理解为什么广告公司会投入大量资源进行这一特定领域的计算机视觉研究。 尽管这个行业通常较为封闭和保守&#xff0c;但偶尔也会在arxiv等公共存储库中发布一些研究&#xff0c;这些研究暗示了更先进的专…...

opencv函数展示

一、图像基础 I/O 与显示 1.cv2.imread() 2.cv2.imshow() 3. cv2.waitKey() 4. cv2.imwrite() 5. cv2.selectROI() 6. cv2.VideoCapture() 二、颜色空间与转换 1. cv2.cvtColor() 2. cv2.split() 三、阈值处理 1. cv2.threshold() 2. 特殊阈值方法...

Redis 的不同数据结构分别适用于哪些微服务场景

我们一块来分析下Redis 的不同数据结构在微服务场景下的具体应用&#xff1a; 1. String (字符串) 特点: 最基本的数据类型&#xff0c;二进制安全&#xff0c;可以存储任何类型的数据&#xff08;文本、序列化对象、图片等&#xff09;&#xff0c;最大 512MB。支持原子性的…...

用node编写git钩子hooks的示例

关于 git 钩子函数&#xff0c;就是在 git 进行提交的时候触发一些可执行脚本的功能&#xff0c;详情可以看这篇博客【GIT知识】git进阶-hooks勾子脚本_git hooks-CSDN博客&#xff0c;我这里稍微演示一下怎么用 node 编写钩子的脚本 以 pre-commit 钩子为例&#xff0c;会在用…...