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

Linux系统编程_进程间通信第1天:IPC、无名管道pipe和命名管道mkfifo(半双工)、消息队列msgget(全双工)

1. 进程间通信概述(427.1)

在这里插入图片描述

2. 管道通信原理(428.2)

  • 进程间的五种通信方式介绍
    • https://blog.csdn.net/wh_sjc/article/details/70283843
  • 进程间通信(IPC,InterProcess Communication):在不同进程之间传播或交换信息(*面试会问)
    • IPC的方式通常有管道(无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式

2.1 特点

  1. 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。
  2. 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
  3. 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

2.2 原型

#include <unistd.h>
int pipe(int fd[2]);    // 返回值:若成功返回0,失败返回-1
  • 当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图:
  • 要关闭管道只需将这两个文件描述符关闭即可。
    在这里插入图片描述

2.3 例子

  • 单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:
  • 若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。

在这里插入图片描述

#include<stdio.h>
#include<unistd.h>int main(){int fd[2];  // 两个文件描述符pid_t pid;char buff[20];if(pipe(fd) < 0)  // 创建管道printf("Create Pipe Error!\n");if((pid = fork()) < 0)  // 创建子进程printf("Fork Error!\n");else if(pid > 0){  // 父进程close(fd[0]);  // 关闭读端write(fd[1],"hello world\n",12);}else{			   //子进程close(fd[1]);  // 关闭写端read(fd[0],buff,20);printf("%s",buff);}return 0;
}

在这里插入图片描述

3. 管道编程实战(429.3)(无名管道)

  • IPC/demo1.c(无名管道,父进程向子进程写入字符串)
#include <stdio.h>
#include <unistd.h>//标准c库 pipe fork
#include <string.h>
#include <stdlib.h>//标准c库 exit
#include <sys/types.h>
#include <sys/wait.h>//waitint main(){int fd[2];pid_t pid;char buf[128];
//	int pipe(int pipefd[2]);if(pipe(fd) == -1){   //创建管道printf("creat pipe failed\n");}pid = fork();         //创建子进程if(pid<0){printf("creat child failed\n");}else if(pid > 0){     //父进程sleep(3);		  //休眠确保子进程先运行,到read时阻塞,3s后父进程往下走printf("this is father\n");close(fd[0]); //关闭读端write(fd[1],"hello from father",strlen("hello form father"));wait(NULL);}else{		      //子进程printf("this is child\n");close(fd[1]); //关闭写端read(fd[0],buf,128);printf("read from father: %s\n",buf);exit(0);}return 0;
}

在这里插入图片描述

4. 创建命名管道(4)

FIFO,也称为命名管道,它是一种文件类型(半双工)

4.1 特点

  • FIFO 可以在无关的进程之间交换数据,与无名管道不同。
  • FIFO 有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

4.2 原型

#include <sys/stat.h>
// 返回值:成功返回0,出错返回-1
int mkfifo(const char *pathname, mode_t mode);
  • 其中的 mode 参数与 open函数中的 mode 相同。一旦创建了一个 FIFO,就可以用一般的文件I/O函数操作它。
  • 当 open 一个FIFO时,是否设置非阻塞标志(O_NONBLOCK)的区别:
    • 若没有指定O_NONBLOCK(默认),只读 open 要阻塞到某个其他进程为写而打开此 FIFO。类似的,只写 open 要阻塞到某个其他进程为读而打开它。
    • 若指定了O_NONBLOCK,则只读 open 立即返回。而只写 open 将出错返回 -1 如果没有进程已经为读而打开该 FIFO,其errno置ENXIO。

4.3 例子

  • FIFO 的通信方式类似于在进程中使用文件来传输数据,只不过 FIFO 类型文件同时具有管道的特性。在数据读出时,FIFO 管道中同时清除数据,并且“先进先出”。下面的例子演示了使用 FIFO 进行 IPC 的过程:
  • IPC/demo2.c(仅创建)
#include <sys/types.h>
#include <sys/stat.h>//mkfifo的int main(){//int mkfifo(const char *pathname, mode_t mode);mkfifo("./file",0600);//创建管道,权限为可读可写return 0;
}
  • IPC/demo3.c(简单调试:文件已存在,错误)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>int main(){//int mkfifo(const char *pathname, mode_t mode);int ret = mkfifo("./file",0600);if(ret == 0){printf("mkfifo suscceess\n");}if(ret == -1){printf("mkfifo failed\n");perror("why");}		return 0;
}

在这里插入图片描述

  • IPC/demo4.c(效果同demo3)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include<errno.h>int main(){
//int mkfifo(const char *pathname, mode_t mode);if( (mkfifo("./file",0600) == -1) && errno==EEXIST){printf("mkfifo failed\n");perror("why");}else{if(errno= =EEXIST){printf("file exists\n");}elseprintf("mkfifo suscceess\n");}		return 0;
}

在这里插入图片描述

  • IPC/demo5.c(创建管道,且只有在错误不是 EEXIST 时才打印错误消息)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include<errno.h>int main(){
//int mkfifo(const char *pathname, mode_t mode);if( (mkfifo("./file",0600) == -1) && errno!=EEXIST){//只有在错误不是 EEXIST 时才打印错误消息perror("mkfifo failed");}return 0;
}

5. 命名管道的数据通信编程实现(430.5)

  • IPC/demo6.c(没有指定O_NONBLOCK(默认),只读 open 要阻塞到某个其他进程为写而打开此 FIFO)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include<errno.h>
#include <fcntl.h>int main(){
//int mkfifo(const char *pathname, mode_t mode);if( (mkfifo("./file",0600) == -1) && errno!=EEXIST){printf("mkfifo failuer\n");perror("why");}int fd = open("./file",O_RDONLY);//若没有指定O_NONBLOCK(默认)printf("open success\n");//只读 open 要阻塞到某个其他进程为写而打开此 FIFO//close(fd);return 0;
}
  • IPC/writedemo6.c(没有指定O_NONBLOCK(默认),只写 open 要阻塞到某个其他进程为读而打开它)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include<errno.h>
#include <fcntl.h>int main(){int fd = open("./file",O_WRONLY);//若没有指定O_NONBLOCK(默认)printf("write open success\n");//只写 open 要阻塞到某个其他进程为读而打开它//close(fd);return 0;
}
  • IPC/read.c(读5次)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h> // O_WRONLY open
#include <string.h>//strlen
#include <unistd.h>//write
//int mkfifo(const char *pathname, mode_t mode);
int main(){char buf[30] = {0};//int nread = 0;int cnt = 0;if( (mkfifo("./file",0600) == -1) && errno!=EEXIST){//创建fifo管道printf("mkfifo failed\n");perror("why");}int fd = open("./file",O_RDONLY);printf("open success\n");while(1){int nread = read(fd,buf,30);//读内容printf("read %d byte from fifo,context:%s\n",nread,buf);cnt++;if(cnt == 5){break;	}}close(fd);return 0;
}
  • IPC/write.c(写5次)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h> // O_WRONLY open
#include <string.h>//strlen
#include <unistd.h>//write
//int mkfifo(const char *pathname, mode_t mode);
int main(){int cnt = 0;char *str = "I'm Message from fifo_write";int fd = open("./file",O_WRONLY);printf("write open success\n");while(1){write(fd, str, strlen(str));//写内容cnt++;sleep(1);if(cnt == 5){break;	}}close(fd);return 0;
}

在这里插入图片描述

6. 消息队列的通信原理(6)

消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识

特点

  1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。
  2. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
    在这里插入图片描述

7. 消息队列相关api(431.7)

在这里插入图片描述
在这里插入图片描述

原型

#include <sys/msg.h>
// 创建或打开消息队列:成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);//通过key(非负数 索引值)找到对应消息队列,打开队列的方式//返回值是消息队列的标识符
// 添加消息:成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag);//flag为0是默认阻塞的方式添加消息
// 读取消息:成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);//long type消息类型,用于找到对应消息,flag为0是默认阻塞的方式读取消息
// 控制消息队列:成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • 在以下两种情况下,msgget将创建一个新的消息队列:
    • 如果没有与键值 key 相对应的消息队列,并且 flag 中包含了 IPC_CREAT 标志位。
    • key 参数为 IPC_PRIVATE。
  • 函数 msgrcv 在读取消息队列时,type 参数有下面几种情况:
    • type == 0,返回队列中的第一个消息;
    • type > 0,返回队列中消息类型为 type 的第一个消息;
    • type < 0,返回队列中消息类型值小于或等于 type 绝对值的消息,如果有多个,则取类型值最小的消息。
  • 可以看出,type 值非 0 时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值。(其他的参数解释,请自行Google之)
    在这里插入图片描述

8. 消息队列编程收发数据(432.8)

在这里插入图片描述

  • IPC/msgGet.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//       int msgget(key_t key, int msgflg);
//       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{long mtype;       /* message type, must be > 0 */char mtext[256];    /* message data */
};int main(){struct msgbuf readBuf;	int msgId = msgget(0x1234,IPC_CREAT|0777);//创建/打开消息队列,通过key找到对应消息队列,可读可写可执行if(msgId == -1 ){printf("get que failed\n");//创建/打开失败}msgrcv(msgId, &readBuf,sizeof(readBuf.mtext),888,0);//读取消息	printf("read from que:%s\n",readBuf.mtext);struct msgbuf sendBuf = {988,"thank you for reach"};msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//添加消息return 0;
}
  • IPC/msgSend.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//       int msgget(key_t key, int msgflg);
//       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf {long mtype;       /* message type, must be > 0 */char mtext[256];    /* message data */
};int main(){struct msgbuf sendBuf = {888,"this is message from quen"};	int msgId = msgget(0x1234, IPC_CREAT|0777);//创建/打开消息队列,通过key找到对应消息队列,可读可写可执行if(msgId == -1 ){printf("get que failed\n");}msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//添加消息printf("send over\n");struct msgbuf readBuf;msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);//读取消息printf("reaturn from get:%s\n",readBuf.mtext);return 0;
}

9. 键值生成及消息队列移除(9)

在这里插入图片描述

  • IPC/msgGet.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//       int msgget(key_t key, int msgflg);
//       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
//int msgctl(int msqid, int cmd, struct msqid_ds *buf);
struct msgbuf{long mtype;       /* message type, must be > 0 */char mtext[256];    /* message data */
};int main(){struct msgbuf readBuf;	key_t key;key = ftok(".",'m');printf("key=%x\n",key);int msgId = msgget(key,IPC_CREAT|0777);//创建/打开消息队列,通过key找到对应消息队列,可读可写可执行if(msgId == -1 ){printf("get que failuer\n");}//memset(&readBuf,0,sizeof(struct msgbuf));msgrcv(msgId, &readBuf,sizeof(readBuf.mtext),888,0);//读取消息	printf("read from que:%s\n",readBuf.mtext);struct msgbuf sendBuf = {988,"thank you for reach"};msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//添加消息msgctl(msgId,IPC_RMID,NULL);//控制消息队列,将消息队列从内核中删除return 0;
}
  • IPC/msgSend.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//       int msgget(key_t key, int msgflg);
//       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
//int msgctl(int msqid, int cmd, struct msqid_ds *buf);
struct msgbuf {long mtype;       /* message type, must be > 0 */char mtext[256];    /* message data */
};int main(){struct msgbuf sendBuf = {888,"this is message from quen"};	key_t key;key = ftok(".",'m');printf("key=%x\n",key);int msgId = msgget(key, IPC_CREAT|0777);//创建/打开消息队列,通过key找到对应消息队列,可读可写可执行if(msgId == -1 ){printf("get que failuer\n");}msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//添加消息printf("send over\n");struct msgbuf readBuf;//memset(&readBuf,0,sizeof(struct msgbuf));msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);//读取消息printf("reaturn from get:%s\n",readBuf.mtext);msgctl(msgId,IPC_RMID,NULL);//控制消息队列,将消息队列从内核中删除return 0;
}

相关文章:

Linux系统编程_进程间通信第1天:IPC、无名管道pipe和命名管道mkfifo(半双工)、消息队列msgget(全双工)

1. 进程间通信概述&#xff08;427.1&#xff09; 2. 管道通信原理&#xff08;428.2&#xff09; 进程间的五种通信方式介绍 https://blog.csdn.net/wh_sjc/article/details/70283843 进程间通信&#xff08;IPC&#xff0c;InterProcess Communication&#xff09;&#xff…...

figma+windows系统

...

typescript实现一个简单的区块链

TypeScript 是一种由 Microsoft 推出的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;允许程序员使用面向对象的方式编写代码&#xff0c;并提供类型检查和语法提示等优秀的开发体验。区块链技术是一种分布式的、可靠的、不可篡改的数据库技术&#xff0c;用于记…...

服务器被暴力破解怎么解决

暴力破解分两种&#xff0c;一种是SSH暴力破解&#xff0c;属于Linux服务器。一种是RDP暴力破解&#xff0c;属于Windows服务器。两者其实攻击手法一样&#xff0c;都是黑客利用扫描工具对某一个IP段扫描&#xff0c;而Linux跟Windows登录端口为别是22和3389。那怎样才能有效避…...

用来生成二维矩阵的dcgan

有大量二维矩阵作为样本&#xff0c;为连续数据。数据具有空间连续性&#xff0c;因此用卷积网络&#xff0c;通过dcgan生成二维矩阵。因为是连续变量&#xff0c;因此损失采用nn.MSELoss()。 import torch import torch.nn as nn import torch.optim as optim import numpy a…...

免费的国产数据集成平台推荐

在如今的数字化时代下&#xff0c;企业内部的数据无疑是重要资产之一。随着数据源的多样性和数量剧增&#xff0c;如何有效地收集、整合、存储、管理和分析数据变得至关重要。为了解决这些常见痛点&#xff0c;数据集成平台成为了现代企业不可或缺的一部分。 数据集成是现代数…...

【yolov8系列】yolov8的目标检测、实例分割、关节点估计的原理解析

1 YOLO时间线 这里简单列下yolo的发展时间线&#xff0c;对每个版本的提出有个时间概念。 2 yolov8 的简介 工程链接&#xff1a;https://github.com/ultralytics/ultralytics 2.1 yolov8的特点 采用了anchor free方式&#xff0c;去除了先验设置可能不佳带来的影响借鉴Genera…...

5256C 5G终端综合测试仪

01 5256C 5G终端综合测试仪 产品综述&#xff1a; 5256C 5G终端综合测试仪主要用于5G终端、基带芯片的研发、生产、校准、检测、认证和教学等领域。该仪表具备5G信号发送功能、5G信号功率特性、解调特性和频谱特性分析功能&#xff0c;支持5G终端的产线高速校准及终端发射机…...

Springboot Actuator 环境搭建踩坑

JMX和Springboot Actuator JMX是Java Management Extensions&#xff0c;它是一个Java平台的管理和监控接口。 为什么要搞JMX呢&#xff1f;因为在所有的应用程序中&#xff0c;对运行中的程序进行监控都是非常重要的&#xff0c;Java应用程序也不例外。我们肯定希望知道Java…...

Vue-3.3ESLint

ESLint代码规范 代码规范&#xff1a;一套写代码的约定规则。 JavaScript Standard Style规范说明https://standardjs.com/rules-zhcn.html 代码规范错误 如果你的代码不符合standard的要求&#xff0c;ESlint会跳出来提醒。 比如&#xff1a;在mian.js中随意做一些改动&a…...

STROBE-MR

Welcome to the STROBE-MR website! About: STROBE-MR stands for “Strengthening the Reporting of Observational Studies in Epidemiology using Mendelian Randomization”. Inspired by the original STROBE checklist, the STROBE-MR guidelines were developed to ass…...

Hive安装配置 - 内嵌模式

文章目录 一、Hive运行模式二、安装配置内嵌模式Hive&#xff08;一&#xff09;下载hive安装包&#xff08;二&#xff09;上传hive安装包&#xff08;三&#xff09;解压缩hive安装包&#xff08;四&#xff09;配置hive环境变量&#xff08;五&#xff09;关联Hadoop&#x…...

html中登录按钮添加回车键登录

原文链接有3种方法&#xff0c;其它2中不会弄&#xff0c;第二种方法成功&#xff0c;下面详细说说 原html的登录部分是 <button class"btn btn-success btn-block waves-effect waves-light" id"button" >登入</button> 在该html中增加 &…...

PCL 空间两平面交线计算

PCL 空间两平面交线计算 std::vector<float> LineInPlanes(std::vector<double> para1, std::vector<double> para2) {std::vector<float...

交替合并字符串

题目要求 给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 示例 示例 1&#xff1a; 输入&#xff1a;word1 …...

Linux考试复习整理

文章目录 Linux考试整理一.选择题1.用户的密码现象放置在哪个文件夹&#xff1f;2.删除文件或目录的命令是&#xff1f;3.显示一个文件最后几行的命令是&#xff1f;4.删除一个用户并同时删除用户的主目录5.Linux配置文件一般放在什么目录&#xff1f;6.某文件的组外成员的权限…...

基于geojson-vt和canvas的高性能出图

概述 本文介绍基于geojson-vt和canvas&#xff0c;实现node端高性能出图。 效果 实现 1. canvas绘图 import { createCanvas } from canvasconst tileSize 256; const canvas createCanvas(tileSize, tileSize) const ctx canvas.getContext(2d)2. 处理geojson const g…...

CTF是黑客大赛?新手如何入门CTF?

CTF是啥 CTF 是 Capture The Flag 的简称&#xff0c;中文咱们叫夺旗赛&#xff0c;其本意是西方的一种传统运动。在比赛上两军会互相争夺旗帜&#xff0c;当有一方的旗帜已被敌军夺取&#xff0c;就代表了那一方的战败。在信息安全领域的 CTF 是说&#xff0c;通过各种攻击手…...

电脑开不了机用U盘重装系统Win10教程

如果我们遇到了电脑开不起机的问题&#xff0c;这给我们的正常使用带来了很大的影响。这时候我们可以借助U盘重装系统的方法&#xff0c;轻松应对这一问题。下面小编给大家详细介绍关于用U盘给开不机的电脑重装Win10系统的教程步骤&#xff0c;操作后用户就能正常使用电脑了。 …...

四叉堆在GO中的应用-定时任务timer

堆作为必须掌握的数据结构之一&#xff0c;在众多场景中也得到了广泛的应用。 比较典型的&#xff0c;如java中的优先队列PriorityQueue、算法中的TOP-K问题、最短路径Dijkstra算法等&#xff0c;在这些经典应用中堆都担任着灵魂般的角色。 理论基础 binary heap 再一起回忆…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...