Linux C 进程编程
进程编程
- 进程介绍
- 进程的定义
- 进程和线程以及程序的区别
- 进程块PCB
- 进程的状态
- 相关指令
- 进程调度算法
- 先来先服务调度算法 FCFS
- 短作业(进程)优先调度算法 SJF
- 优先权调度算法 FPF
- 优先权调度算法的类型
- 非抢占式优先权算法
- 抢占式优先权算法
- 优先权类型
- 静态优先权
- 动态优先权
- 高响应比优先调度算法
- 基于时间片的轮转调度算法
- 进程的状态
- 相关函数
- fork 创建子进程
- vfork 创建子进程
- system Shell命令创建子进程
- execl 创建子进程
- 四个创建子进程函数的区别
- 进程的退出
- 进程退出产生的相关问题
- 孤儿进程
- 僵尸进程
- 下面提供了一些解决措施
- 参考文献
进程介绍
进程的定义
官方的来说,进程是程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。
通俗的讲,进程就是在程序编译之后,运行起来的二进制文件。
进程和线程以及程序的区别
程序是存储在磁盘上的可执行文件,是一组指令的集合,它是静态的,而进程包含了程序的代码和程序运行时所需的资源,如内存、文件描述符等。每个进程都是独立的,有自己的地址空间和资源,进程之间是相互独立的。线程则是进程中的执行单元,一个进程可以包含多个线程,这些线程共享进程的资源,包括内存和文件描述符。线程之间可以共享数据,并且可以更高效地进行通信和同步。
因此,进程和线程都是程序的执行实例,它们之间的区别在于资源的独立性和共享性。程序是静态的代码和数据的集合,只有在运行时才会成为进程或线程。
进程块PCB
进程控制块 (PCB)是系统为了管理进程设置的一个专门的数据结构。 系统用它来记录进程的外部特征,描述进程的运动变化过程。 同时,系统可以利用PCB来控制和管理进程,所以说,PCB(进程控制块)是系统感知进程存在的唯一标志。
Linux中可以使用 “ps auxjf” 指令查看进程的静态信息,使用 “top” 指令查看进程的动态信息。
字母 | 解释 |
---|---|
a | 现在一个终端的所有进程 |
u | 显示进程的归属用户以及内存使用情况 |
x | 显示出和终端没有关联的进程 |
j | 显示进程归属的进程组id,会话id,父进程id |
f | 以ascii形式显示出进程的层次关系 |
进程的状态
状态 | 状态属性 |
---|---|
R:执行状态 | <:优先级高的进程,比优先级的进程运行的次数更频繁。 |
S:休眠状态 | N:低优先级的进程 |
Z:僵尸进程 | s:包含子进程 |
T:停止状态 | I:位于后台的进程组 |
D:无法中断的休眠状态 | +:进程组内的前台进程 |
相关指令
1) 进程运行切换
① 在终端后台运行一个进程:./ 可执行命令 空格 &
② 查看终端的后台进程:jobs
③ 让进程n到后台去:bg %n
④ 让后台运行的进程n到前台来:fg %n
⑤ 把前台进程已停止状态进入后台进程:ctrl + z。
注:一个终端只能有一个前台进程,剩余的所有进程都是后台进程。
2) 杀死进程:kill 空格 参数 空格 杀死的目标(进程 ID),常用参数为-9。
进程调度算法
这里只做简单介绍,具体和算法部分可以自行单独搜索。
先来先服务调度算法 FCFS
先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用 FCFS 算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
FCFS 算法比较有利于长作业(进程),而不利于短作业(进程)。
短作业(进程)优先调度算法 SJF
短作业(进程)优先调度算法 SJ§F,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。
SJF 调度算法能有效地降低作业的平均等待时间,提高系统吞吐量。但是该算法对长作业不利,并且不能保证紧迫性作业(进程)会被及时处理。
优先权调度算法 FPF
优先权调度算法的类型
为了照顾紧迫型作业,使之在进入系统后便获得优先处理,引入了最高优先权优先(FPF)调度算法。此算法常被用于批处理系统中,作为作业调度算法,也作为多种操作系统中的进程调度算法,还可用于实时系统中。当把该算法用于作业调度时,系统将从后备队列中选择若干个优先权最高的作业装入内存。当用于进程调度时,该算法是把处理机分配给就绪队列中优先权最高的进程,这时,又可进一步把该算法分成如下两种。
非抢占式优先权算法
在这种方式下,系统一旦把处理机分配给就绪队列中优先权最高的进程后,该进程便一直执行下去,直至完成;或因发生某事件使该进程放弃处理机时,系统方可再将处理机重新分配给另一优先权最高的进程。
这种调度算法主要用于批处理系统中;也可用于某些对实时性要求不严的实时系统中。
抢占式优先权算法
在这种方式下,系统同样是把处理机分配给优先权最高的进程,使之执行。但在其执行期间,只要又出现了另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理机分配给新到的优先权最高的进程。因此,在采用这种调度算法时,是每当系统中出现一个新的就绪进程 i 时,就将其优先权 Pi 与正在执行的进程 j 的优先权 Pj 进行比较。如果 Pi≤Pj,原进程 Pj 便继续执行;但如果是 Pi>Pj,则立即停止 Pj 的执行,做进程切换,使 i 进程投入执行。
显然,这种抢占式的优先权调度算法能更好地满足紧迫作业的要求,故而常用于要求比较严格的实时系统中,以及对性能要求较高的批处理和分时系统中。
优先权类型
对于最高优先权优先调度算法,其关键在于:它是使用静态优先权,还是用动态优先权,以及如何确定进程的优先权。
静态优先权
静态优先权是在创建进程时确定的,且在进程的整个运行期间保持不变。一般地,优先权是利用某一范围内的一个整数来表示的,例如,0~7 或 0~255 中的某一整数,又把该整数称为优先数,只是具体用法各异:有的系统用“0”表示最高优先权,当数值愈大时,其优先权愈低;而有的系统恰恰相反。
确定进程优先权的依据有如下三个方面:进程类型、进程对资源的需求、用户要求。
动态优先权
动态优先权是指在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。例如,我们可以规定,在就绪队列中的进程,随其等待时间的增长,其优先权以速率 a 提高。若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程将因其动态优先权变得最高而优先获得处理机,此即FCFS 算法。若所有的就绪进程具有各不相同的优先权初值,那么,对于优先权初值低的进程,在等待了足够的时间后,其优先权便可能升为最高,从而可以获得处理机。当采用抢占式优先权调度算法时,如果再规定当前进程的优先权以速率 b 下降,则可防止一个长作业长期地垄断处理机。
高响应比优先调度算法
在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。如果我们能为每个作业引入前面所述的动态优先权,并使作业的优先级随着等待时间的增加而以速率 a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。该优先权的变化规律可描述为:
优先权 = 等待时间 + 要求服务时间 要求服务时间 =\frac{\text { 等待时间 }+ \text { 要求服务时间 }}{\text { 要求服务时间 }} = 要求服务时间 等待时间 + 要求服务时间
由于等待时间与服务时间之和就是系统对该作业的响应时间,故该优先权又相当于响应比 RP。据此,又可表示为:
R P = 等待时间 + 要求服务时间 要求服务时间 = 响应时间 要求服务时间 R_{\mathrm{P}}=\frac{\text { 等待时间 }+ \text { 要求服务时间 }}{\text { 要求服务时间 }}=\frac{\text { 响应时间 }}{\text { 要求服务时间 }} RP= 要求服务时间 等待时间 + 要求服务时间 = 要求服务时间 响应时间
基于时间片的轮转调度算法
如前所述,在分时系统中,为保证能及时响应用户的请求,必须采用基于时间片的轮转式进程调度算法。在早期,分时系统中采用的是简单的时间片轮转法;进入 20 世纪 90年代后,广泛采用多级反馈队列调度算法。
进程的状态
1 ) 就绪(Ready)状态
当进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
2 ) 执行状态
进程已获得 CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
3 ) 阻塞状态
正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求 I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。
相关函数
fork 创建子进程
头文件:
#include<unistd.h>
函数原型::pid_t fork(void);
函数介绍:fork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。父子之间抢占CPU执行。
返回值:如果 fork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回 0。如果 fork 失败则直
接返回-1,失败原因存于 errno 中。
pid_t pid = fork();
vfork 创建子进程
头文件:
#include<unistd.h>
函数原型::pid_t vfork(void);
函数介绍: vfork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。数据空间与父进程共享(全局变量区 文本常量区)。先运行子进程,子进程结束后再运行父进程。
返回值:如果 vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回 0。如果 fork 失败则
直接返回-1,失败原因存于 errno 中。
pid_t pid = vfork();
system Shell命令创建子进程
头文件:
#include<stdlib.h>
函数原型:int system(const char * string);
参数介绍:
string:可执行文件 路径+名字
函数介绍::system()会调用 fork()产生子进程,由子进程来调用/bin/sh-c string 来执行参数 string 字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用 system()期间 SIGCHLD 信号会被暂时搁置,SIGINT 和 SIGQUIT 信号则会被忽略。
返回值:如果 system()在调用/bin/sh 时失败则返回 127,其他失败原因返回-1。若参数 string 为空指针(NULL),则返回非零值。如果 system()调用成功则最后会返回执行 shell 命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh 失败所返回的 127,因此最好能再检查 errno 来确认执行成功。
system("./fun");
execl 创建子进程
头文件:
#include<unistd.h>
函数原型:int execl(const char * path,const char * arg,…);
参数介绍:
path:文件路径+名字
arg:所要传送的参数,最后必须使用NULL作为结束
函数介绍:execl用另一个新程序替换了当前进程的正文、数据、堆和栈段,进程ID不变。
返回值:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于 errno 中。
四个创建子进程函数的区别
函数 | 复制父进程数据 | 是否有自己的独立空间 | 修改数据影响父进程 | 是否创建新进程 |
---|---|---|---|---|
fork | 是 | 是 | 否 | 是 |
vfork | 否 | 否 | 是 | 是 |
system | 否 | 是 | 否 | 是 |
execl | 否 | 是 | 否 | 否 |
进程的退出
进程退出三种方法:return、exit()、_exit()。第二种为常用。
三者的区别:
return:
在函数中使用return语句可以退出当前函数并返回一个值给调用者,但不会结束整个进程。
exit():
exit()是一个库函数,用于正常终止当前进程,并返回一个状态码给操作系统。它会执行一系列清理工作,如关闭文件、释放内存等,然后终止进程。
_exit():
_exit()是一个系统调用,用于立即终止当前进程,不会执行任何清理工作。它直接通知操作系统终止进程,不会触发任何终止处理程序,也不会刷新缓冲区或关闭文件。通常情况下,应该在使用fork()创建子进程后,使用_exit()来终止子进程。
进程退出产生的相关问题
孤儿进程
孤儿进程的本质上还是个普通的进程,是指一个父进程退出,而它的一个或者多个子进程还在运行,那么这些子进程就称为孤儿进程。孤儿进程会被系统指定的进程所收养,并由收养孤儿进程的进程对他们进程完成状态收集工作。注:在“红帽 Linux 系统”中,孤儿进程将被“init 进程(进程号为 1)”的进程所收养,但是在“乌班图 Linux系统中”,是由“upstart 进程”所收养。
僵尸进程
Linux 的进程在结束的时候不会对自己的资源进行清零,只有父进程结束时才会对子进程的资源进程清零。僵尸进程是指子进程先于父进程退出,父进程退出的时候没有回收子进程退出状态的资源(task_struct),因此子进程就称为僵尸进程(孩子寄了,父亲没有收s)。写程序时要尽量避免出现僵尸进程(系统垃圾),利用等待进程退出函数可以解决僵尸进程问题。
下面提供了一些解决措施
1)父进程使用wait()或waitpid()系统调用来回收子进程的资源,避免子进程成为僵尸进程。
2 )使用信号处理机制,在父进程中注册SIGCHLD信号处理函数,当子进程终止时会触发该信号,父进程可以在信号处理函数中回收子进程的资源。
3 )使用守护进程来创建子进程,守护进程会负责回收子进程的资源,避免子进程成为僵尸进程。
参考文献
文章 进程调度算法 和 进程状态 部分内容参考于 《计算机操作系统(第 三 版)》 汤小丹 梁红兵 哲凤屏 汤子瀛 编著
(想要资源的可以私信我,我有PDF版本)
相关文章:

Linux C 进程编程
进程编程 进程介绍进程的定义进程和线程以及程序的区别进程块PCB进程的状态相关指令 进程调度算法先来先服务调度算法 FCFS短作业(进程)优先调度算法 SJF优先权调度算法 FPF优先权调度算法的类型非抢占式优先权算法抢占式优先权算法 优先权类型静态优先权动态优先权 高响应比优…...

Spring Boot (三)
1、热部署 热部署可以替我们节省大把花在重启项目本身上的时间。热部署原理上,一个springboot项目在运行时实际上是分两个过程进行的,根据加载的东西不同,划分成base类加载器与restart类加载器。 base类加载器:用来加载jar包中的类…...
第五章:抽象类
系列文章目录 文章目录 系列文章目录前言一、抽象类二、模板设计模式总结 前言 当我们想让子类来实现方法时,我们需要抽象类与抽象方法。 一、抽象类 当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法…...

NSSCTF web刷题记录5
文章目录 [HZNUCTF 2023 preliminary]ezlogin[MoeCTF 2021]地狱通讯[NSSRound#7 Team]0o0[ISITDTU 2019]EasyPHP[极客大挑战 2020]greatphp[安洵杯 2020]Validator[GKCTF 2020]ez三剑客-ezweb [HZNUCTF 2023 preliminary]ezlogin 考点:时间盲注 打开题目,…...

Spark SQL 每年的1月1日算当年的第一个自然周, 给出日期,计算是本年的第几周
一、问题 按每年的1月1日算当年的第一个自然周 (遇到跨年也不管,如果1月1日是周三,那么到1月5号(周日)算是本年的第一个自然周, 如果按周一是一周的第一天) 计算是本年的第几周,那么 spark sql 如何写 ? 二、分析 …...

WebSocket Day04 : 消息推送
前言 随着Web应用程序的不断发展,实时性和交互性成为了用户体验中至关重要的一部分。传统的HTTP协议在处理实时数据传输方面存在一些局限性,而WebSocket作为一种全双工通信协议,为实现实时、高效的消息推送提供了全新的解决方案。 在Web开发…...

【Hadoop】MapReduce详解
🦄 个人主页——🎐开着拖拉机回家_大数据运维-CSDN博客 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁…...

ctf之流量分析学习
链接:https://pan.baidu.com/s/1e3ZcfioIOmebbUs-xGRnUA?pwd9jmc 提取码:9jmc 前几道比较简单,是经常见、常考到的类型 1.pcap——zip里 流量分析里有压缩包 查字符串或者正则表达式,在包的最底层找到flag的相关内容 我们追踪…...

Linux——vim简介、配置方案(附带超美观的配置方案)、常用模式的基本操作
vim简介、配置方案、常用模式的基本操作 本章思维导图: 注:本章思维导图对应的xmind和.png文件都已同步导入至资源 1. vim简介 vim是Linux常用的文本编辑器,每个Linux账户都独有一个vim编辑器 本篇我们介绍vim最常用的三种模式:…...

在线预览编辑PDF::RAD PDF for ASP.NET
RAD PDF for ASP.NET作为功能最齐全的基于 HTML 的 PDF 查看器、编辑器和 ASP.NET 表单填充器,RAD PDF 为传统 PDF 解决方案提供了灵活而强大的替代方案。与 Adobe Acrobat Reader 不同,RAD PDF 几乎可以在任何现代网络浏览器中运行,…...

【赠书第4期】机器学习与人工智能实战:基于业务场景的工程应用
文章目录 前言 1 机器学习基础知识 2 人工智能基础知识 3 机器学习和人工智能的实战案例 4 总结 5 推荐图书 6 粉丝福利 前言 机器学习与人工智能是当前最热门的领域之一,也是未来发展的方向。随着科技的不断进步,越来越多的企业开始关注和投入机…...

npm封装插件打包上传后图片资源错误
问题: npm封装插件:封装的组件页面涉及使用图片资源,在封装的项目里调用图片显示正常;但是打包上传后,其他项目引入使用报错找不到图片资源;图片路径也不对 获取图片的base64方法 解决方案: 将…...

[云原生案例2.3 ] Kubernetes的部署安装 【多master集群架构高可用 ---- (二进制安装部署)】
文章目录 1. Kubernetes多Master集群高可用方案1.1 多节点Master高可用的实现过程1.2 实现高可用方法 2. 新Master节点的部署2.1 前置准备2.2 系统初始化操作2.2.1 关闭防火墙、selinux和swap分区2.2.2 修改主机名,添加域名映射2.2.3 修改内核参数2.2.4 时间同步 2.…...

归并排序(含递归和非递归版)
以梦为马,不负韶华 文章目录 引入:实现原理问题引出:递归实现:迭代实现稳定性分析:总结: 引入: 如何将两个有序数组(假设为升序)合并为一个有序数组? 双指针…...

微服务的注册发现和微服务架构下的负载均衡
文章目录 微服务注册模型服务注册与发现怎么保证高可用【1. 服务端崩溃检测】【2. 客户端容错】【3. 注册中心选型】 微服务架构下的负载均衡【1.轮询与加权轮询】【2.随机与加权随机】【3.哈希与一致性哈希】【4.最少连接数】【5.最少活跃数】【6.最快响应时间】【总结】 负载…...
从混沌到有序:sortedcontainers库的数据魔法改变你的编程体验
前言 在当今数据爆炸的时代,高效地处理和操作数据成为每位Python开发者的核心任务。在这个背景下,sortedcontainers库以其强大的有序数据结构为程序员提供了处理大规模数据的优越选择。本文将深入研究sortedcontainers库中的主要有序数据结构࿰…...
读取pdf、docx、doc、ppt、pptx并转为txt
文章目录 一、思路构建二、开始实现三、存在的问题3.1 解析doc文档遇到问题及解决方法:3.2 解析ppt文档遇到问题及解决方法: 四、读取pdf中的图片 一、思路构建 Zip文件和初始化文件放在同一个文件夹下;然后解析zip文件读取到一个新的文件夹…...

11.13/14 理解SDK框架遇到的问题
1.1.浮点数打印问题 float red_increment (target_red_value - initial_red_value) / STEPS; u8 STEPS 100; printf("绿色值每一次增量------%f\n", red_increment); 后面三个参数均为u8类型 希望采用 %f打印出每次的步进值。但是结果为空白 希望采用 %.2f打印…...

计算机网络——b站王道考研笔记
第一章 计算机网络体系结构 1.计算机网络概述 (1)概念 计算机网络是一个将分散的,具有独立功能的计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统; 是互连的&#…...
Stm32_标准库_18_串口蓝牙模块_手机与蓝牙模块通信_控制LED灯亮灭
通过输入LED_ON和LED_OFF分别控制LED灯的亮与灭 接线: LED的正极接正电,负极接GPIOA_Pin1 蓝牙模块TXD接GPIOA_Pin3,VCC接正电,GND接负电 注意:USART2是APB1外设,汉字占用字节数是字符的两倍 使用: 手…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...