[Linux]进程间通信-管道
目录
1. 进程间通信
2.父子进程之间的通信
3.匿名管道
匿名管道的创建
管道读写的情况
管道的5种特性
4.命名管道
指令级
命名管道原理
代码级
读取端
1. 进程间通信
当我们有两个进程操作数据库的时候,一个进程负责写入操作,一个进程负责读取操作,如果没有写入完成就进行读取了,那么就会出现数据不一致等问题。亦或者多个进程同时完成一项任务的时候,需要按照某种顺序进行执行的情况等等,这些都需要进程之间进行沟通,所以说采用了进程间通信的机制。
进程间通信就是可以让不同的进程之间可以进行数据传输、资源共享、事件通知以及进程控制等操作,本质上来说就是让不同的进程可以看到同一份资源。这一份资源通常是由操作系统来提供的。
2.父子进程之间的通信
当一个进程创建子进程的时候,会为子进程创建进程PCB,并创建虚拟地址空间、进行页表的映射处理。但是对于管理文件的struct file_struct结构体是浅拷贝,那么也就是说,父子进程的文件描述符表是共用的,当进行修改的时候,会发生写时拷贝操作。但是无论如何,文件描述符表里的内容在修改之前是一样的,所以说父进程文件描述符对应的文件和子进程的是一样的,所以说相当于父子进程就可以看到同一份资源了。
其实子进程可以说大多数的指针指向的内容的拷贝都属于是浅拷贝,在不修改的时候都是和父进程共用一份资源的,页表也是如此,如果不修改页表的前提下,就没有必要在为子进程单独创建一个页表了,而且页表是采用的分级结构的,当需要修改的时候,为修改的部分单独创建一个第二层映射关系;而子进程则只需要创建一个第一层的页表,然后修改第一层页表中改变部分的指向就可以了。
那么如何进行通信呢?父进程可以分别通过读和写的方式打开同一个文件,那么就会产生两个文件描述符,假设3为读取,4为写入 。那么创建子进程后,子进程会继承父进程的文件描述符表,也就会看到3和4号文件描述符,那么父进程关闭3号文件描述符,子进程关闭4号文件描述符有,这样的话,就变成了一个单向通道了,父进程负责写入,子进程负责接收数据。这样就实现了父子进程之间的进程通信了。如图所示:
一个进程以不同的方式打开同一个文件时,会产生多个文件描述符对应多个struct file结构体,这里是不可以合并的,因为是以不同的方式打开的,所以对于文件的操作不同,而struct file结构体就记录了如何操作该文件,所以说必须创建多个。但是多个struct file结构体对应指向的文件是相同的一个。(同一个inode、同一个方法集等)同时创建多个struct file也可以配合引用计数的机制,引用计数通过统计有多少个struct file结构体指向该文件,防止关闭了一个文件描述符,但是其他文件描述符还指向该文件的情况下将文件关闭了,或者说父子进程同时指向该文件时,一次关闭文件描述符就将该文件关闭了。
引用计数也使得进程管理和文件管理进行解耦了,进程不需要关心什么时候关闭文件,当引用计数减少到0的时候,操作系统会自动关闭该文件。
如果说想让父子都可以进行读写操作的话,建立两个这样的文件逻辑就可以了。
3.匿名管道
管道文件时内存级别的文件,而且和上述操作一样,只能进行单向通信。管道和上述提供的文件一样,都是属于一块父子进程都可以访问到的公共资源空间,父子进程通过该空间就实现了通信的逻辑。只不过管道是由操作系统帮我们创建的一块临时的空间而已。
匿名管道的创建
int pipe(int fd[2]); 头文件 <unistd.h>
该函数成功的时候返回0,失败返回-1,同时错误码被设置。fd属于输入输出型参数,返回的fd[0]表述读端,fd[1]表示写端。
在命令行中,我们使用的 ‘ | ’ 就是匿名管道。例如ls -al | grep "a.out",就是将ls命令显示的数据重定向输出到管道文件中,grep指令输入重定向从管道文件中取出数据。
管道读写的情况
(1)当管道中没有数据的时候,读端会等待,直到由数据为止。
(2)如果管道被写满了,读端也没有进行读取的话,写端在写入的时候就会等待,直到有空间写入为止。
(3)读端关闭的情况,写端还进行写入的话,操作系统会像写端进程发送SICPIPE13号信号杀死进程。但是这样往往是不合理的,可以使用信号处理函数改变信号默认处理策略,而不是直接杀死进程
(4)写端关闭的话,无论是阻塞读取还是非阻塞读取,read函数在读取完缓冲区的数据后,都会返回0,表示对端关闭了。
管道的5种特性
匿名管道用于具有血缘关系的进程之间进行进程间的通信,常用于父子进程;匿名管道默认是给读写两端提供了同步机制(上述的前两点);面向的是字节流;管道的生命周期是跟随进程的;半双工通信(单向通信)。
4.命名管道
命名管道与匿名管道最大的区别在于命名管道可以让两个无关系的进程之间进行通信,而匿名管道只能应用于父子或有血缘关系的进程之间进行通信。命名管道是一类特殊的文件类型,他也是一种文件,像普通文件一样可以被多个进程打开和操作,在打开的时候,操作系统也要为其创建struct file结构体映射到文件描述符表中等各种操作。
指令级
mkfifo filename指令
上述说了命名管道就是一种特殊的文件,所以说可以通过路径和文件名的方式在任何地方去访问该文件,利用该文件进行进程之间的通信。下面就是一个进程之间通信的例子,使用了echo和cat进程指令:
但是当我们操作的时候会发现,在使用cat读取管道文件内容之前,echo指令会卡在原地,没有真正的写入到命名管道文件当中,我们查看管道文件也会发现大小为0。这是为什么呢?因为命令管道主要的目的是进程之间的传递信息,而不是像普通文件一样为了将数据存放到磁盘当中,他的数据传递主要是基于进程之间的同步机制的。
echo操作时,会将字符串发送到命名管道的写入端,但是,由于命令管道的同步特性,如果没有进程在读取端准备接收数据时,数据就会暂时停留在管道的缓冲区中,也就是echo进程的命名管道文件struct file结构体关联的文件缓冲区当中。而当cat指令执行的时候,读取端就做好了准备,所以触发了命名管道的读取操作,此时,echo才会真正的将数据从文件缓冲区中写入命名管道文件当中。
命名管道原理
原理上其实根匿名管道类型,匿名管道这一公共资源区域是由操作系统创建和完成的。而命名管道是我们自己创建的。底层上和打开文件一样,打开命名管道文件,为该文件创建struct file结构体,映射到文件描述符表中。然后两个进程同时打开的该命名管道文件的话,两个进程就可以通过各自的struct file看到该管道文件了。通过该管道文件就可以实现进程之间的通信了。
其实这个底层操作和上述说的父子进程之间的同意基本一致,最主要的区别是管道文件是专门用于进程之间通信的,提供了同步的机制,而普通文件是没有这种机制的。还有一个就是在命名管道的通信是在命名管道的文件缓冲区中,而并非是在写入和读取命名管道。
struct file内部记录了该进程对于该文件的处理方式,所以会有多个指向同一个文件,但是对于打开的文件,操作系统只需要维护一份就够了,操作系统会将打开的文件用先描述再组织的方式管理起来,每个结构体内部记录文件的属性和各种字段,同时还由文件的缓冲区等内容。
由上图也可以看出来,其实两个进程并非是直接关联的命名管道,而是关联的命名管道的缓冲区,两者进行数据沟通也是在缓冲区内部进行的。
代码级
int mkfifo(const char* pathname, mode_t mode);
在代码中也是一样的,一个进程打开命名管道之后,会进行等待,直到读写端都打开了之后,才会继续往下运行。
读取端
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define PIPE_FILE "pipe_file"void CreatePipeFile()
{//创建命名管道文件mkfifo(PIPE_FILE, 0666);
}int main()
{//以读的方式打开管道文件,如果不存在就创建命名管道int fd = -1;while(1){fd = open(PIPE_FILE, O_RDONLY);if(fd < 0){CreatePipeFile();}else{break;}}//读取内容while(1){char buffer[1024];int ret = read(fd, buffer, sizeof(buffer) - 1);//读取出错if(ret < 0){return -1;}//对端关闭了写操作else if(ret == 0){std::cout << "write server is close" << std::endl;return 0;}//输出读取内容else{buffer[ret] = '\0';std::cout << buffer << std::endl;}}close(fd);return 0;
}
写入端
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>#define PIPE_FILE "pipe_file"int main()
{//以写的形式打开文件int fd = open(PIPE_FILE, O_WRONLY);//向管道文件中写入数据while(1){char input[1024];std::cin >> input;int n = write(fd, input, strlen(input));if(n < 0){return -1;}}close(fd);return 0;
}
相关文章:
[Linux]进程间通信-管道
目录 1. 进程间通信 2.父子进程之间的通信 3.匿名管道 匿名管道的创建 管道读写的情况 管道的5种特性 4.命名管道 指令级 命名管道原理 代码级 读取端 1. 进程间通信 当我们有两个进程操作数据库的时候,一个进程负责写入操作,一个进…...
设置开机自启动的应用
设置开机自启动的应用 step1:按住ShiftctrlEsc step2:找到启动应用 step3:鼠标到启动那里,右键就可以禁用了...
QQ长截屏
QQ长截屏 第一步:CtrlAltA 第二步:点击剪刀之后,再滑动滚轮就可以了。 展示...
38 Opencv HOG特征检测
文章目录 HOGDescriptor 构造函数setSVMDetector 设置支持向量机(SVM)检测器,用于目标检测。compute 用于计算图像区域的HOG描述符。detectMultiScale 多尺度检测目标。示例 HOGDescriptor 构造函数 HOGDescriptor(); HOGDescriptor(const S…...
Segment Anything论文详细翻译【Part2:引言Introduction】
目录 写在前面 Introduction 第1段 第2段 第3段 第4段 第5段 第6段 第7段 第8段 第9段 第10段 第11段 第12段 Figure2 关键特点 图中具体内容 图例说明 写在前面 为啥要写这篇文章?因为找不到一篇写的特别好的【翻译并仔细解释】文章。网上大多千…...
Mac中配置Node.js前端vscode环境(第二期)
核心组件:vscode、谷歌浏览器、Node.js(重点)、git 一、Node.js安装(nvm安装) 点击macos中的终端,保持bash,而不是zsh 若为zsh,则可在终端中使用下面命令变成bash chsh -s /bin/…...
基于COT(Chain-of-Thought Prompt)的教学应用:如何通过思维链提示提升模型推理能力
引言 随着人工智能技术的快速发展,大型语言模型(LLMs)在自然语言处理领域展现出了强大的能力。然而,面对复杂的推理任务时,模型的表现往往不尽如人意,尤其是在需要多步逻辑推导的场景中。为了应对这一挑战…...
Python Notes 1 - introduction with the OpenAI API Development
Official document:https://platform.openai.com/docs/api-reference/chat/create 1. Use APIfox to call APIs 2.Use PyCharm to call APIs 2.1-1 WIN OS.Configure the Enviorment variable #HK代理环境,不需要科学上网(价格便宜、有安全风险&#…...
MySQL图形化界面工具--DataGrip
之前介绍了在命令行进行操作,但是不够直观,本次介绍图形化界面工具–DataGrip。 安装DataGrip 官网链接:官网下载链接 常规的软件安装流程。 参考链接:DataGrip安装 使用DataGrip 添加数据源: 第一次使用最下面会…...
WPF+Prism View与ViewModel绑定
1、开发环境,Win10VS2022.NET8Prism.DryIoc(9.0.537)或Prism.Unity。 2、通过NuGet安装Prism.DryIoc(9.0.537)或Prism.Unity。 2.1、创建ViewModels文件夹用于存放ViewModel文件、创建Views文件夹存放View文件。 将…...
关于Zotero
1、文献数据库: Zotero的安装 Zotero安装使用_zotero只能安装在c盘吗-CSDN博客 2、如何使用zotero插件 我刚下载的时候就结合使用的是下面的这两个博主的分享,感觉暂时是足够的。 Zotero入🚪基础 - 小红书 Green Frog申请easyscholar密钥…...
Luma AI 简单几步生成视频
简单几步生成视频 登录我们的 AceDataPlatform 网站,按照下图所示即可生成高质量的视频,同时,我们也提供了简单易用的 API 方便集成调用,可以查看 Luma API了解详情 技术介绍 我们使用了 Luma 的技术,实现了上面的图…...
从索尼爱立信手机打印短信的简单方法
昨天,我买了一部新手机来代替我的旧索尼爱立信Xperia,但手机上有很多珍贵的短信,是我男朋友发来的,我不想失去它们。然后我尝试打印它们,但我无法从我的索尼爱立信手机中取出它们。您有什么从索尼爱立信手机打印短信的…...
深入浅出梯度下降算法:快速抵达函数最小值的方法
引言 梯度是机器学习和优化领域中不可或缺的概念,它为我们提供了理解和调整多维空间中函数行为的工具。本文将详细介绍梯度的定义、性质,并通过具体的一元和多元函数案例展示如何使用梯度下降算法找到最佳参数。 一、梯度的基础知识 1.1 定义与计算 梯…...
OPC DA激活报错
报错提示: 解决办法: 查看Missing license keys,根据提示破解...
PyTorch到C++再到 CUDA 的调用链(C++ ATen 层) :以torch._amp_update_scale_调用为例
今天在看pytorch源码,遇到的问题,记录一下 。 source:/lib/python3.10/site-packages/torch/amp/grad_scaler.py torch._amp_update_scale_(_scale,_growth_tracker,found_inf_combined,self._growth_factor,self._backoff_factor,self._growth_interva…...
yolov5核查数据标注漏报和误报
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、误报二、漏报三、源码总结 前言 本文主要用于记录数据标注和模型预测之间的漏报和误报思想及其源码 提示:以下是本篇文章正文内容,…...
C# 设计模式概况
什么是设计模式 大家熟知的GOF23种设计模式,源自《Design Patterns: Elements of Reusable Object-Oriented Software》一书,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著,四人组Gang of Four简称GOF。总结了在面向…...
STM32 NOR FLASH(SPI FLASH)驱动移植(2)
2)FLASH 读取函数 /* * brief 读取 SPI FLASH * note 在指定地址开始读取指定长度的数据 * param pbuf : 数据存储区 * param addr : 开始读取的地址(最大 32bit) * param datalen : 要读取的字节数(最大 65535) * retval 无 */ void norflash_read(uint8_t *pbuf…...
Redis高可用集群部署
根据集群分析和持久化优化方式,这里用docker部署redis分片集群模式并设置为aof-rdb共用方式存储 准备 2核4G及以上服务器;安装好docker环境;配置docker镜像仓库(https://www.ecnfo.com:1443),因为下面镜像是从这个镜像仓库下载的{"builder": {"gc"…...
【玩转23种Java设计模式】行为型模式篇:命令模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...
代码随想录算法【Day10】
今日只做一题,剩下的题后面补 232.用栈实现队列 class MyQueue { public:stack<int> stIn;stack<int> stOut;/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {stIn.push(x);}…...
WKWebView打开pdf文件乱码?各种方案整理。
近期有用户反馈使用我们FinClip SDK运行的小程序,在iOS18.0.1的系统上打开部分pdf文件的时候出现了乱码的现象, 低版本的系统打开没有出现乱码的现象,用电脑打开这个pdf文件也是正常的。经过排查,可能是iOS18的系统对WKWebView进行了调整处理…...
Android中创建ViewModel的几种方法
文章目录 1. 使用 `ViewModelProvider`1.1 在 `Activity` 中创建 `ViewModel`1.2 在 `Fragment` 中创建 `ViewModel`2. 使用 `ViewModelFactory`2.1 创建 `ViewModel` 和 `ViewModelFactory`2.2 在 `Activity` 或 `Fragment` 中使用 `ViewModelFactory`3. 使用 `by viewModels(…...
【C语言】_指针运算
目录 1. 指针-整数 2. 指针-指针 2.1 指针-指针含义 2.2 指针-指针运算应用:实现my_strlen函数 3. 指针的关系运算(大小比较) 1. 指针-整数 联系关于指针变量类型关于指针类型和指针-整数相关知识: 原文链接如下࿱…...
多层设计模式:可否设计各层之间公用的数据定义模块?
在多层程序设计模式中,可以设计一个各层之间公用的数据类型定义模块。这种模块通常被称为“公共模块”或“共享模块”,它包含所有层都需要使用的数据类型定义。这有助于确保数据在不同层之间传递时的一致性和准确性。 以下是一些设计这种公用数据类型定…...
深度学习模型格式转换:pytorch2onnx(包含自定义操作符)
将PyTorch模型转换为ONNX(Open Neural Network Exchange)格式是实现模型跨平台部署和优化推理性能的一种常见方法。PyTorch 提供了多种方式来完成这一转换,以下是几种主要的方法: 一、静态模型转换 使用 torch.onnx.export() t…...
CDPHudi实战-集成spark
[一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do scp /opt/software/hudi-1.0.0/packaging/hudi-spark-bundle/target/hudi-spark3.4-bundle_2.12-1.0.0.jar cdp73-$i:/opt/cloudera/parcels/CDH/lib/spark3/jars/; done hudi-spark3.4-bu…...
Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s
前言:纯个人记录使用。 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。 官方文档…...
汇编语言与接口技术--跑马灯
一、 实验要求 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图: 单片机芯片选择AT89C51,晶振频率设为12MHz,操作参考单片机开发板使用说明。跑马灯点亮的时间间隔约为1秒。分别用定时器的模式1和模式2实现。(用P83…...
springcloud篇3-docker需熟练掌握的知识点
docker的原理请参考博文《Docker与Kubernetes》。 一、安装docker的指令 1.1 安装yum工具 yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken补充:配置镜像源 注意: yum安装是在线联网下载安装,而很多的资源…...
Unity网络通信相关
Socket 通信一张图搞定 谁提供服务谁绑定端口,建立Listener,写Host...
leetcode 173.二叉搜索树迭代器栈绝妙思路
以上算法题中一个比较好的实现思路就是利用栈来进行实现,以下方法三就是利用栈来进行实现的,思路很好,很简练。进行next的时候,先是一直拿到左边的子树,直到null为止,这一步比较好思考一点,下一…...
模电面试——设计题及综合分析题0x01(含答案)
1、已知某温控系统的部分电路如下图(EDP070252),晶体管VT导通时,继电器J吸合,压缩机M运转制冷,VT截止时,J释放,M停止运转。 (1)电源刚接通时,晶体…...
Linux性能优化-系列文章-汇总
前言 Linux性能优化,涉及了CPU,内存,磁盘,网络等很多方面,一方面涉及的知识面广,同时又要在原理方面掌握一定的深度。所以整理总结了Linux性能优化的一系列文章。当处理Linux性能问题的时候,可…...
仓库叉车高科技安全辅助设备——AI防碰撞系统N2024G-2
在当今这个高效运作、安全第一的物流时代,仓库作为供应链的中心地带,其安全与效率直接关系到企业的命脉。 随着科技的飞速发展,传统叉车作业模式正逐步向智能化、安全化转型,而在这场技术革新中,AI防碰撞系统N2024G-2…...
threejs 安装
参考了threejs官方网站文档安装,上来就是各种报错,最终参考之前大佬发的攻略解决了。过程供大家参考。 官方文档地址如下: three.js docshttps://threejs.org/docs/index.html#manual/en/introduction/Installation 具体参考这篇攻略&#…...
《 C++ 点滴漫谈: 十七 》编译器优化与 C++ volatile:看似简单却不容小觑
摘要 本文深入探讨了 C 中的 volatile 关键字,全面解析其基本概念、典型用途以及在现代编程中的实际意义。通过剖析 volatile 的核心功能,我们了解了它如何避免编译器优化对硬件交互和多线程环境中变量访问的干扰。同时,文章分析了 volatile…...
【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习
文章目录 Section 4:The Vim Help System(Vim 帮助系统)S04L14 Getting Help1 打开帮助系统2 退出帮助系统3 查看具体命令的帮助文档4 查看帮助文档中的主题5 帮助文档间的上翻、下翻6 关于 linewise7 查看光标所在术语名词的帮助文档8 关于退…...
电脑中缺失的nvrtc64_90.dll文件如何修复?
一、文件丢失问题 案例:nvrtc64_90.dll文件缺失 问题分析: nvrtc64_90.dll是NVIDIA CUDA Runtime Compilation库的一部分,通常与NVIDIA的CUDA Toolkit或相关驱动程序一起安装。如果该文件丢失,可能会导致基于CUDA的应用程序&…...
leveldb的DBSequence从哪里来,到哪里去?
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) leveldb数据库的DBSequence从哪里来,到哪里去? 大概的情形是,leveldb的记录初始DBSequence为0,随着记录的增加,记录sequence不断随着增加,并持久化…...
nginx高可用集群搭建
本文介绍nginx高可用集群的搭建。利用keepalived实时检查nginx进程是否存活、keepalived的虚拟ip技术,达到故障转移的目的。终端用户通过访问虚拟ip,感知不到实际发生的故障。架构图如下: 0、环境 Ubuntu:22.04.2 ltsnginx: 1.…...
基于TCP的Qt网络通信
基于TCP的Qt网络通信 项目源码:https://github.com/say-Hai/TcpSocketLearn/tree/QTcpSocket 在标准C没有提供专门用于套接字通信的类,所以只能使用操作系统提供的基于C的API函数,但是Qt就不一样了,它是C的一个框架并且里边提供了…...
MySql---进阶篇(六)---SQL优化
6.1:insert的优化: (1)普通的插入数据 如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化。 insert into tb_test values(1,tom); insert into tb_test values(2,cat); insert into tb_test values(3,jerry); 1). 优…...
什么是回归测试?
什么是回归测试? 回归测试被定义为一种软件测试,以确认最近的程序或代码更改没有对现有功能产生不利影响。回归测试只是对已经执行的测试用例的全部或部分选择,重新执行这些用例以确保现有功能正常工作。 进行此测试是为了确保新的代码更改不会对现有…...
详解MySQL SQL删除(超详,7K,含实例与分析)
文章目录 前言1. 删除表中的所有记录基本语法使用场景注意事项运用实例分析说明2. 删除特定记录基本语法使用场景注意事项运用实例分析说明3. 删除单条记录基本语法使用场景注意事项运用实例分析说明4. 删除违反引用完整性的记录基本语法使用场景注意事项运用实例分析说明5. 删…...
lec7-路由与路由器
lec7-路由与路由器 1. 路由器硬件 路由器的硬件部分: 断电失去: RAM断电不失去:NVRAM, Flash, ROMinterface也算是一部分 路由器是特殊组件的计算机 console 口进行具体的调试 辅助口(Auxiliary&…...
知识库召回列表模式揭秘:实现智能信息检索新突破
目录 一、什么是知识库的召回列表模式 召回列表模式的工作流程 典型应用场景 召回列表模式的优势 二、知识库召回列表模式的技术实现细节 1. 数据准备 2. 召回策略 3. 排序策略 4. 结果展示与交互 三、技术架构示例 1. 系统架构 2. 代码示例 四、总结 随着人工智能…...
WCH的CH57X的J-LINK的芯片FLASH烧录文件
WCH的CH57X的J-LINK的芯片FLASH烧录文件,需要在 D:\app\Keil_v5\SEGGER\JLink_V616a目录中JLINKDEVICES.XML文件中修改并增加以下信息。同时,需要加入CH57X.FLM文件 <Device> <ChipInfo Vendor"WCH" Name"CH57X" WorkRAMAddr"…...
Rust 基础入门指南
Rust 基础入门指南 1. Rust 语言概述 Rust 的历史与设计理念 Rust 是由 Mozilla 研究院的 Graydon Hoare 于2010年开始创建的系统编程语言。其设计目标是创建一种安全、并发、实用的编程语言,特别关注内存安全和并发性。 Rust 的核心设计理念包括: …...