IO进程线程day8(2023.8.6)
一、Xmind整理:
管道的原理:
有名管道的特点:
信号的原理:
二、课上练习:
练习1:pipe
功能:创建一个无名管道,同时打开无名管道的读写端
原型:
#include <unistd.h>
int pipe(int pipefd[2]); int* pfd; int pfd[]
参数:
int pipefd[2]:函数运行完毕后,该参数指向的数组中会存储两个文件描述符;
pipefd[0]: 读端文件描述符;
pipefd[1]: 写端文件描述符;
返回值:
成功,返回0;
失败,返回-1,更新errno;
小练:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//管道的创建必须放在fork函数前//若放在fork函数后,会导致父子进程各自创建一根管道//此时会导致父子进程各自操作各自的管道,无法进行通信int pfd[2] = {0};if(pipe(pfd) < 0){perror("pfd");return -1;}printf("pipe success pfd[0]=%d pfd[1]=%d\n",pfd[0],pfd[1]);pid_t cpid = fork();if(cpid > 0) //父进程中为真{//父进程发送数据给子进程char buf[128]="";while(1){fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0; //从终端获取数据,最后会拿到\n字符,将\n字符修改成0//将数据写入到管道文件中if(write(pfd[1],buf,sizeof(buf)) < 0){perror("write");return -1;}printf("写入成功\n");}}else if(0 == cpid) //子进程中为真{//子进程读取父进程发送过来的数据char buf[128] = "";ssize_t res = 0;while(1){bzero(buf,sizeof(buf));printf("__%d__\n",__LINE__);//当管道中没有数据的时候,read函数阻塞res = read(pfd[0],buf,sizeof(buf));printf("res=%ld : %s\n",res,buf); }}else{perror("fork");return -1;}return 0;
}
练习2:mkfifo
功能:创建一根有名管道
原型:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
参数:
char *pathname:指定要创建的有名管道的路径以及名字;
mode_t mode:有名管道的权限:0664 0777,真实的权限 (mode & ~umask)
the permissions of the created file are (mode & ~umask)
返回值:
成功,返回0;
失败,返回-1,更新errno;
errno == 17,文件已经存在的错误,这是一个允许存在的错误,忽略该错误
练习3:操作有名管道
功能:操作有名管道与用文件IO操作普通文件一致
原型:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
参数:
int flags:O_RDONLY 只读O_WRONLY 只写O_RDWR 读写---上述三种必须,且只能包含一种---O_NONBLOCK 非阻塞
1.int flags == O_RDONLY
open函数阻塞,此时需要另外一个进程或线程以写的方式打开同一根管道,open函数解除阻塞
2.int flags == O_WRONLY
open函数阻塞,此时需要另外一个进程或线程以读的方式打开同一根管道,open函数解除阻塞
3.int flags == O_RDWR
open函数不阻塞,此时管道的读写端均被打开
当管道的读写端均被打开的时候,此时open函数不阻塞
4.int flags == O_RDONLY | O_NONBLOCK
open函数不阻塞,open函数运行成功,此时管道只有读端
5.int flags == O_WRONLY | O_NONBLOCK
open函数不阻塞,open函数运行失败,此时管道的读写端均打开失败
示例:
读端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>int main(int argc, const char *argv[])
{umask(0);if(mkfifo("./fifo", 0777) < 0){//printf("errno = %d\n", errno);if(errno != 17) //17 == EEXIST{perror("mkfifo");return -1;}}printf("create FIFO success\n");//open函数阻塞int fd = open("./fifo", O_RDONLY);if(fd < 0){perror("open");return -1;}printf("open FIFO rdonly success fd=%d\n", fd);char buf[128] = "";ssize_t res = 0;while(1){bzero(buf, sizeof(buf));res = read(fd, buf, sizeof(buf));if(res < 0){perror("read");return -1; }else if(0 == res){printf("对端关闭\n");break;}printf("%ld :%s\n", res, buf);}close(fd);return 0;
}
写端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>int main(int argc, const char *argv[])
{umask(0);if(mkfifo("./fifo", 0777) < 0){ //printf("errno = %d\n", errno);if(errno != 17) //17 == EEXIST{perror("mkfifo");return -1; }} printf("create FIFO success\n");//open函数阻塞int fd = open("./fifo", O_WRONLY);if(fd < 0){ perror("open");return -1; } printf("open FIFO wronly success fd=%d\n", fd);char buf[128] = ""; while(1){ printf("请输入>>>");fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = 0;if(write(fd, buf, sizeof(buf)) < 0){perror("write");return -1; }printf("写入成功\n");} close(fd);return 0;
}
小练:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//创建有名管道if(mkfifo("./fifo",0664) < 0){//printf("%d\n",errno);if(errno != 17) //17:文件已经存在错误,这是一个允许存在的错误,忽略该错误{perror("mkfifo");return -1;}}printf("mkfifo success\n");/*int fd = open("./fifo",O_RDWR);if(fd < 0){perror("open");return -1;}printf("open success fd = %d\n",fd);
*/int fd_r = open("./fifo",O_RDONLY|O_NONBLOCK);if(fd_r < 0){perror("open");return -1;}printf("open success fd_r = %d\n",fd_r);int fd_w = open("./fifo",O_WRONLY|O_NONBLOCK);if(fd_w < 0){perror("open");return -1;}printf("open success fd_w = %d\n",fd_w);return 0;
}
练习4:常见的信号
练习5:signal
功能:捕获信号,为信号注册新的处理函数
原型:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler); //void (*handler)(int);
参数:
int signum:指定要捕获的信号对应的编号。可以填编号,也可以填对应的宏。2) SIGINT
sighandler_t handler:函数指针,回调函数;
1) SIG_IGN:忽略信号; 9) 19)号信号无法忽略;
2) SIG_DFL:执行默认操作;
3) 传入一个函数的首地址,代表捕获信号,且该函数的返回值必须是void类型,参数列表必须是int类型,例如:void handler(int sig){ }
typedef void (*sighandler_t)(int); typedef void (*)(int) sighandler_t;
typedef 旧的类型名 新的类型名;
typedef int uint32_t; int a ----> uint32_t a;
typedef int* pint; int* pa ---> pint pa;
typedef void (*)(int) sighandler_t; void (*ptr)(int) ----> sighandler_t ptr;
返回值:
成功,返回该信号的上一个信号处理函数的首地址; 默认处理函数的首地址获取不到,返回NULL;
失败,返回SIG_ERR ((__sighandler_t)-1),更新errno;
小练:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <head.h>
void handler(int sig)
{printf("this is sig=%d\n",sig);return;
}
int main(int argc, const char *argv[])
{//捕获2号SIGINT信号if(signal(2,handler) == SIG_ERR){perror("signal");return -1;}printf("捕获2号信号成功\n");//捕获3号SIGINT信号if(signal(3,handler) == SIG_ERR){perror("signal");return -1;}printf("捕获3号信号成功\n");//捕获20号SIGINT信号if(signal(20,handler) == SIG_ERR){perror("signal");return -1;}printf("捕获20号信号成功\n");while(1){printf("this is main func\n");sleep(1);}return 0;
}
三、课后作业:
1.要求实现AB进程对话
A进程先发送一句话给B进程,B进程接收后打印
B进程再回复一句话给A进程,A进程接收后打印
重复1.2步骤,当收到quit后,要结束AB进程
提示:两根管道
A进程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//创建有名管道if(mkfifo("./fifo",0664) < 0){//printf("%d\n",errno);if(errno != 17) //17:文件已经存在错误,这是一个允许存在的错误,忽略该错误{perror("mkfifo");return -1;}}printf("mkfifo success\n");if(mkfifo("./fifo1",0664) < 0){//printf("%d\n",errno);if(errno != 17) //17:文件已经存在错误,这是一个允许存在的错误,忽略该错误{perror("mkfifo");return -1;}}printf("mkfifo1 success\n");int fd_r= open("./fifo",O_RDONLY);if(fd_r < 0){perror("open");return -1;}printf("open success fd_r = %d\n",fd_r);int fd_w = open("./fifo1",O_WRONLY);if(fd_w < 0){perror("open");return -1;}printf("open success fd_w= %d\n",fd_w);//从管道中读取数据,打印到终端上char buf[128]="";ssize_t res = 0;while(1){bzero(buf,sizeof(buf));//当管道的读写端均存在,若管道中没有数据,则read函数阻塞res = read(fd_r,buf,sizeof(buf));if(strcmp(buf,"quit") == 0){write(fd_w,buf,sizeof(buf));break;}if(res < 0){perror("read");return -1;}if(0 == res){printf("写端关闭\n");break;}printf("res =%ld\n输出:%s\n",res,buf);bzero(buf, sizeof(buf));printf("请输入:");fgets(buf, sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';if(write(fd_w,buf,sizeof(buf))< 0){perror("write");return -1;}printf("写入数据成功 res =%ld\n",res);}close(fd_r);close(fd_w);return 0;
}
B进程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//创建有名管道if(mkfifo("./fifo",0664) < 0){//printf("%d\n",errno);if(errno != 17) //17:文件已经存在错误,这是一个允许存在的错误,忽略该错误{perror("mkfifo");return -1;}}printf("mkfifo success\n");if(mkfifo("./fifo1",0664) < 0){//printf("%d\n",errno);if(errno != 17) //17:文件已经存在错误,这是一个允许存在的错误,忽略该错误{perror("mkfifo");return -1;}}printf("mkfifo1 success\n");int fd_w = open("./fifo",O_WRONLY);if(fd_w < 0){perror("open");return -1;}printf("open success fd_w= %d\n",fd_w);int fd_r= open("./fifo1",O_RDONLY); if(fd_r < 0){perror("open");return -1;}printf("open success fd_r = %d\n",fd_r);//从终端获取数据,写到管道中char buf[128]="";ssize_t res = 0;while(1){bzero(buf, sizeof(buf));printf("请输入:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';if(strcmp(buf,"quit") == 0){write(fd_w,buf,sizeof(buf));break;}if(write(fd_w,buf,sizeof(buf)) < 0){perror("write");return -1;}printf("写入数据成功 res =%ld\n",res);bzero(buf,sizeof(buf));//当管道的读写端均存在,若管道中没有数据,则read函数阻塞res = read(fd_r,buf,sizeof(buf));if(res < 0){perror("read");return -1;}if(0 == res){printf("写端关闭\n");break;}printf("res =%ld\n输出:%s\n",res,buf);}close(fd_w);close(fd_r);return 0;
}
2.在第1题的基础上实现,A能随时发信息给B,B能随时接收A发送的数据,反之亦然。
A进程:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>int main(int argc, const char *argv[])
{if(mkfifo("./fifo", 0775) < 0) //当前进程写该管道{if(17 != errno) //#define EEXIST 17{perror("mkfifo");return -1;}}printf("fifo create success\n");if(mkfifo("./fifo1", 0775) < 0) //当前进程读该管道{if(17 != errno) //#define EEXIST 17{perror("mkfifo");return -1;}}printf("fifo1 create success\n");//创建一个子进程pid_t cpid = fork();if(cpid > 0){//读 fifo1int fd_r = open("./fifo1", O_RDONLY); //阻塞if(fd_r < 0){perror("open");return -1;}printf("open fifo rdonly success __%d__\n", __LINE__);ssize_t res = 0;char buf[128] = "";while(1){bzero(buf, sizeof(buf));//读写段均存在,且管道中没有数据,该函数阻塞res = read(fd_r, buf, sizeof(buf));if(res < 0){perror("read");return -1;}else if(0 == res){printf("对端进程退出\n");break; }printf("res=%ld : buf=%s\n", res, buf);if(!strcmp(buf, "quit"))break;}close(fd_r);kill(cpid, 9);wait(NULL);}else if(0 == cpid){//写 fifoint fd_w = open("./fifo", O_WRONLY); //阻塞if(fd_w < 0){perror("open");return -1;}printf("open fifo wronly success __%d__\n", __LINE__);char buf[128] = "";while(1){bzero(buf, sizeof(buf));// printf("请输入>>>");fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = 0;if(write(fd_w, buf, sizeof(buf)) < 0){perror("write");return -1;}// printf("写入成功\n");if(!strcmp(buf, "quit"))break;}close(fd_w);kill(getppid() , 9);}else{perror("fork");return -1;}return 0;
}
B进程:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>int main(int argc, const char *argv[])
{if(mkfifo("./fifo", 0775) < 0) //当前进程写该管道{if(17 != errno) //#define EEXIST 17{perror("mkfifo");return -1;}}printf("fifo create success\n");if(mkfifo("./fifo1", 0775) < 0) //当前进程读该管道{if(17 != errno) //#define EEXIST 17{perror("mkfifo");return -1;}}printf("fifo1 create success\n");//创建一个子进程pid_t cpid = fork();if(cpid > 0){//读 fifoint fd_r = open("./fifo", O_RDONLY); //阻塞if(fd_r < 0){perror("open");return -1;}printf("open fifo rdonly success __%d__\n", __LINE__);ssize_t res = 0;char buf[128] = "";while(1){bzero(buf, sizeof(buf));//读写段均存在,且管道中没有数据,该函数阻塞res = read(fd_r, buf, sizeof(buf));if(res < 0){perror("read");return -1;}else if(0 == res){printf("对端进程退出\n");break; }printf("res=%ld : buf=%s\n", res, buf);if(!strcmp(buf, "quit"))break;}close(fd_r);kill(cpid, 9);wait(NULL);}else if(0 == cpid){//写 fifo1int fd_w = open("./fifo1", O_WRONLY); //阻塞if(fd_w < 0){perror("open");return -1;}printf("open fifo wronly success __%d__\n", __LINE__);char buf[128] = "";while(1){bzero(buf, sizeof(buf));//printf("请输入>>>");fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = 0;if(write(fd_w, buf, sizeof(buf)) < 0){perror("write");return -1;}// printf("写入成功\n");if(!strcmp(buf, "quit"))break;}close(fd_w);kill(getppid() , 9);}else{perror("fork");return -1;}return 0;
}
相关文章:

IO进程线程day8(2023.8.6)
一、Xmind整理: 管道的原理: 有名管道的特点: 信号的原理: 二、课上练习: 练习1:pipe 功能:创建一个无名管道,同时打开无名管道的读写端 原型: #include <unist…...

【5G NR】逻辑信道、传输信道和物理信道的映射关系
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…...
tmux基础教程
tmux基础教程 Mac安装 brew install tmuxubuntu安装 sudo apt-get install tmux入门使用 会话 (Session) Ctrlb d: 分离当前会话。Ctrlb s: 列出所有会话。Ctrlb $: 重命名当前会话。 窗口(Window) Ctrlb c: 创建一个新窗口, 状态栏会显示多个窗…...

项目实战 — 消息队列(4){消息持久化}
目录 一、消息存储格式设计 🍅 1、queue_data.txt:保存消息的内容 🍅 2、queue_stat.txt:保存消息的统计信息 二、消息序列化 三、自定义异常类 四、创建MessageFileManger类 🍅 1、约定消息文件所在的目录和文件名…...

AI编程工具Copilot与Codeium的实测对比
csdn原创谢绝转载 简介 现在没有AI编程工具,效率会打一个折扣,如果还没有,赶紧装起来. GitHub Copilot是OpenAi与github等共同开发的的AI辅助编程工具,基于ChatGPT驱动,功能强大,这个没人怀疑…...

webpack基础知识六:说说webpack的热更新是如何做到的?原理是什么?
一、是什么 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用 例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致…...

Linux从安装到实战 常用命令 Bash常用功能 用户和组管理
1.0初识Linux 1.1虚拟机介绍 1.2VMware Workstation虚拟化软件 下载CentOS; 1.3远程链接Linux系统 &FinalShell 链接finalshell半天没连接进去 他说ip adress 看IP地址是在虚拟机上 win11主机是 终端输入: ifconfig VMware虚拟机的设置 & ssh连接_snge…...

webpack基础知识三:说说webpack中常见的Loader?解决了什么问题?
一、是什么 loader 用于对模块的"源代码"进行转换,在 import 或"加载"模块时预处理文件 webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。如下图所示&#…...
深度学习:Pytorch常见损失函数Loss简介
深度学习:Pytorch常见损失函数Loss简介 L1 LossMSE LossSmoothL1 LossCrossEntropy LossFocal Loss 此篇博客主要对深度学习中常用的损失函数进行介绍,并结合Pytorch的函数进行分析,讲解其用法。 L1 Loss L1 Loss计算预测值和真值的平均绝对…...
【Android-java】Parcelable 是什么?
Parcelable 是 Android 中的一个接口,用于实现将对象序列化为字节流的功能,以便在不同组件之间传递。与 Java 的 Serializable 接口不同,Parcelable 的性能更高,适用于 Android 平台。 要实现 Parcelable 接口,我们需…...
Spring整合MyBatis小实例(转账功能)
实现步骤 一,引入依赖 <!--仓库--><repositories><!--spring里程碑版本的仓库--><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>https://repo.spring.i…...

List集合的对象传输的两种方式
说明:在一些特定的情况,我们需要把对象中的List集合属性存入到数据库中,之后把该字段取出来转为List集合的对象使用(如下图) 自定义对象 public class User implements Serializable {/*** ID*/private Integer id;/*…...

海外媒体发稿:软文写作方法方式?一篇好的软文理应合理规划?
不同种类的软文会有不同的方式,下面小编就来来给大家分析一下: 方法一、要选定文章的突破点: 所说突破点就是这篇文章文章软文理应以什么样的视角、什么样的见解、什么样的语言设计理念、如何文章文章的标题来写。不同种类的传播效果&#…...

【秋招】算法岗的八股文之机器学习
目录 机器学习特征工程常见的计算模型总览线性回归模型与逻辑回归模型线性回归模型逻辑回归模型区别 朴素贝叶斯分类器模型 (Naive Bayes)决策树模型随机森林模型支持向量机模型 (Support Vector Machine)K近邻模型神经网络模型卷积神经网络(CNN)循环神经…...

为什么list.sort()比Stream().sorted()更快?
真的更好吗? 先简单写个demo List<Integer> userList new ArrayList<>();Random rand new Random();for (int i 0; i < 10000 ; i) {userList.add(rand.nextInt(1000));}List<Integer> userList2 new ArrayList<>();userList2.add…...
SQL账户SA登录失败,提示错误:18456
错误代码 18456 表示 SQL Server 登录失败。这个错误通常表示提供的凭据(用户名和密码)无法成功验证或者没有权限访问所请求的数据库。以下是一些常见的可能原因和解决方法: 1.错误的凭据:请确认提供的SA账户的用户名和密码是否正…...

Linux 终端操作命令(1)
Linux 命令 终端命令格式 command [-options] [parameter] 说明: command:命令名,相应功能的英文单词或单词的缩写[-options]:选项,可用来对命令进行控制,也可以省略parameter:传给命令的参…...
java与javaw运行jar程序
运行jar程序 一、java.exe启动jar程序 (会显示console黑窗口) 1、一般用法: java -jar myJar.jar2、重命名进程名称启动: echo off copy "%JAVA_HOME%\bin\java.exe" "%JAVA_HOME%\bin\myProcess.exe" myProcess -jar myJar.jar e…...
安装和配置 Home Assistant 教程 HACS Homkit 米家等智能设备接入
安装和配置 Home Assistant 教程 简介 Home Assistant 是一款开源的智能家居自动化平台,可以帮助你集成和控制各种智能设备,从灯光到温度调节器,从摄像头到媒体播放器。本教程将引导你如何在 Docker 环境中安装和配置 Home Assistant&#…...

解决 Android Studio 的 Gradle 面板上只有关于测试的 task 的问题
文章目录 问题描述解决办法 笔者出问题时的运行环境: Android Studio Flamingo | 2022.2.1 Android SDK 33 Gradle 8.0.1 JDK 17 问题描述 笔者最近发现一个奇怪的事情。笔者的 Android Studio 的 Gradle 面板上居然除了用于测试的 task 之外,其它什…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...