C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)
目录
前言
一、system V IPC对象图解
1.流程图解:
编辑
2.查看linux内核中的ipc对象:
二、消息队列
1.消息队列的原理
2.消息队列相关的API
2.1 获取或创建消息队列(msgget)
实例代码如下:
2.2 发送消息到消息队列中
实例代码如下:
2.3 从消息队列中获取消息
实例代码如下:
2.4 消息队列相关的命令
2.5 管理消息队列
实例代码如下:
三、共享内存
1.概念
2.原理图解
3.相关的api函数
3.1 创建共享内存对象
实例代码如下:
3.2 映射共享内存
3.3 取消映射
实例代码reader.c如下:
实例代码writer.c如下:
实例代码shm.h 如下:
3.4 管理共享内存
实例代码如下:
四、信号灯 (信号量)
1.概念
2.信号灯相关的api函数
2.1 创建或获取信号灯对象
实例代码如下:
2.2 实现P操作和V操作
实例代码如下:
2.3 管理信号灯
实例代码如下:
总结
前言
System V IPC(Inter-Process Communication)对象是一种用于在不同进程之间进行通信的机制。它包括三种类型的对象:消息队列(Message Queue)、信号量(Semaphore)和共享内存(Shared Memory)。
一、system V IPC对象图解
1.流程图解:

2.查看linux内核中的ipc对象:

二、消息队列
1.消息队列的原理

2.消息队列相关的API
2.1 获取或创建消息队列(msgget)
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgget(key_t key, int msgflg);
//参数1 ----- key :
动态获取key: ftok()
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
//参数1 ---- 工程目录
//参数2 ---- 工程编号
//返回值 ----- 成功,返回key值,失败:-1
静态分配: IPC_PRIVATE
//参数2 ------ msgflg:如果消息队列不存在,需要给出创建的关键字,并设置权限 IPC_CREAT | 0666
//返回值 ----- 成功:消息队列的ID,失败:-1
实例代码如下:
int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}return 0;
}
2.2 发送消息到消息队列中
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//参数1 ----- 消息队列的id
//参数2 ----- 指向struct msgbuf结构体的指针,该结构体需要自己定义,如下:
struct msgbuf {
long mtype; /* message type, must be > 0 消息类型*/
char mtext[1]; /* message data 消息正文*/
};
//参数3 ---- 要发送的消息的长度
//参数4 ---- msgflg值如下:
IPC_NOWAIT 消息没有发送完成函数也会立即返回。
0:直到发送完成函数才返回
//返回值 --- 成功:0,失败:-1
实例代码如下:
int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}//向消息队列中发送消息while(1){bzero(&buf,sizeof(buf));printf("请输入消息的类型:");scanf("%ld",&buf.mtype);printf("请输入消息:");while(getchar() != '\n'); //清空输入缓冲区fgets(buf.mtext,sizeof(buf.mtext),stdin);buf.mtext[strlen(buf.mtext)-1] = '\0';if(msgsnd(msg_id,&buf,strlen(buf.mtext),0) < 0){perror("msgsnd");exit(1);}}return 0;
}
2.3 从消息队列中获取消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
//参数1 ----- 消息队列的id
//参数2 ----- 指向struct msgbuf结构体的指针,该结构体需要自己定义,如下:
struct msgbuf {
long mtype; /* message type, must be > 0 消息类型*/
char mtext[1]; /* message data 消息正文*/
};
//参数3 ---- mtext的长度
//参数4 ---- msgtyp:要接收的消息类型
msgtyp > 0 ,表示接收指定类型的消息
msgtyp = 0 ,按先后顺序依次接收不同类型消息
msgtyp < 0 ,优先接收消息类型不大于|msgtyp|的最小类型的消息
//参数5 ---- msgflg值如下:
IPC_NOWAIT 消息没有发送完成函数也会立即返回。
0:直到发送完成函数才返回
//返回值 --- 成功:0,失败:-1
实例代码如下:
int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}//从消息队列中获取消息while(1){bzero(&buf,sizeof(buf));printf("请输入消息的类型:");scanf("%ld",&buf.mtype);if(msgrcv(msg_id,&buf,sizeof(buf.mtext),buf.mtype,0) < 0){perror("msgsnd");exit(1);}printf("msg:%s\n",buf.mtext);}return 0;
}
2.4 消息队列相关的命令
peter@ubuntu:~/2308/proc/day04_code$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x0a010356 0 peter 666 61 5peter@ubuntu:~/2308/proc/day04_code$ ipcrm -q 0
peter@ubuntu:~/2308/proc/day04_code$ ipcs -q------ Message Queues --------
key msqid owner perms used-bytes messages
2.5 管理消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
//参数1 ---- 消息队列ID
//参数2 ---- 功能码:
IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中。
IPC_SET:设置消息队列的属性。这个值取自buf参数。
IPC_RMID:从系统中删除消息队列。
//参数3 ----struct msqid_ds 结构体指针
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
实例代码如下:
int main(int argc,char **argv)
{int msg_id;msg_id = atoi(argv[1]);if(msgctl(msg_id,IPC_RMID,NULL) < 0){perror("msgget");exit(1);}return 0;
}
三、共享内存
1.概念
共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝
为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间
进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。
由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等
2.原理图解

3.相关的api函数
3.1 创建共享内存对象
头文件:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
//参数1 ---- 动态获取key: ftok()
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
//参数1 ---- 工程目录
//参数2 ---- 工程编号
//返回值 ----- 成功,返回key值,失败:-1
静态分配: IPC_PRIVATE
//参数2 ---- 要创建或获取的共享内存的大小
//参数3 ---- 权限:IPC_CREAT | 0666
//返回值 ---- 成功:共享内存ID,失败:-1
实例代码如下:
int main(void)
{key_t key;int shm_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}return 0;
}
3.2 映射共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
//参数1 ---- 共享内存ID
//参数2 ---- 指定进程虚拟空间的映射的起始地址,一般为NULL:让系统分配一个起始地址
//参数3 ---- 访问权限:SHM_RDONLY:共享内存只读
默认0:共享内存可读写
//返回值 --- 成功:映射的虚拟空间地址,失败:-1
3.3 取消映射
int shmdt(const void *shmaddr);
//参数 ----映射的虚拟空间的起始地址
//返回值 ----成功:0,失败:-1
实例代码reader.c如下:
#include "shm.h"int main(void)
{key_t key;int shm_id;char *buf;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}//将共享内存映射到进程的虚拟空间中buf = (char*)shmat(shm_id,NULL,0);if(buf < 0){perror("shmat");exit(1);}//打印共享内存中的数据while(1){printf("%s",buf);sleep(1);}//解除映射if(shmdt(buf) < 0){perror("shmdt");exit(1);}return 0;
}
实例代码writer.c如下:
#include "shm.h"int main(void)
{key_t key;int shm_id;char *buf;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}//将共享内存映射到进程的虚拟空间中buf = (char*)shmat(shm_id,NULL,0);if(buf < 0){perror("shmat");exit(1);}//向共享内存写数据while(1){printf("请输入字符串:");fgets(buf,SHM_SIZE,stdin);}//解除映射if(shmdt(buf) < 0){perror("shmdt");exit(1);}return 0;
}
实例代码shm.h 如下:
#ifndef __SHM_H__
#define __SHM_H__#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define SHM_SIZE 1024#endif
3.4 管理共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//参数1 ---- 共享内存的ID
//参数2 ---- 功能码:
IPC_STAT (获取对象属性)
IPC_SET (设置对象属性)
IPC_RMID (删除对象)
//参数3 ----struct shmid_ds 结构体指针
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
实例代码如下:
int main(int argc,char **argv)
{int shm_id;shm_id = atoi(argv[1]);if(shmctl(shm_id,IPC_RMID,NULL) < 0){perror("shmget");exit(1);}return 0;
}
四、信号灯 (信号量)
1.概念
信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。
信号灯种类:
posix有名信号灯
posix基于内存的信号灯(无名信号灯)
System V信号灯(IPC对象)1》 二值信号灯:用于表示资源是否可用
值为0或1。与互斥锁类似,资源可用时值为1,不可用时值为0。2》 计数信号灯:用于表示资源的数量
值在0到n之间。用来统计资源,其值代表可用资源数3》 等待操作,也称为P操作
是等待信号灯的值变为大于0,然后将其减1;
4》 释放操作,也称为V操作
用来唤醒等待资源的进程或者线程5》System V的信号灯是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。而Posix信号灯指的是单个计数信号灯
2.信号灯相关的api函数
2.1 创建或获取信号灯对象
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
//参数1 ---- 动态获取key: ftok()
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
//参数1 ---- 工程目录
//参数2 ---- 工程编号
//返回值 ----- 成功,返回key值,失败:-1
静态分配: IPC_PRIVATE
//参数2 ---- 集合中信号灯的个数
//参数3 ---- 访问权限:IPC_CREAT | 0666
//返回值 ---- 成功:信号灯对象ID,失败:-1
实例代码如下:
int main(void)
{key_t key;int sem_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象sem_id = semget(key,1, IPC_CREAT|0666);if(sem_id < 0){perror("semget");exit(1);}return 0;
}
2.2 实现P操作和V操作
int semop(int semid, struct sembuf *sops, size_t nsops);
//参数1 ----- 信号灯对象的ID
//参数2 ----- 结构体指针
struct sembuf {
short sem_num; // 要操作的信号灯的编号
short sem_op; // 0 : 等待,直到信号灯的值变成0
// 1 : 释放资源,V操作
// -1 : 分配资源,P操作
short sem_flg; // 0, IPC_NOWAIT, SEM_UNDO
};//参数3 -----nops: 要操作的信号灯的个数
//返回值 ---- 成功:0,失败:-1
实例代码如下:
//1》实现P操作void sem_p(int sem_id,int index){struct sembuf buf = {index,-1,0};if(semop(sem_id,&buf,1) < 0){perror("semop");exit(1);}}
//2》实现v操作void sem_v(int sem_id,int index){struct sembuf buf = {index,1,0};if(semop(sem_id,&buf,1) < 0){perror("semop");exit(1);}}
2.3 管理信号灯
int semctl(int semid, int semnum, int cmd, ...);
//参数1 ---- 信号灯对象ID
//参数2 ---- 集合中信号灯的编号
//参数3 ---- 功能码:
IPC_STAT ----获取信号灯对象属性
IPC_SET ----设置信号灯对象属性
IPC_RMID ----从内核中删除信号灯对象
SETALL ----设置集合中所有信号灯的值
SETVAL ----设置集合中编号为semnum的信号灯的值
//参数4 ---- 联合体变量,类型如下:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
//返回值 -----成功:0,失败:-1
实例代码如下:
//初始化指定的信号灯
void sem_init(int sem_id,int semnum,int value)
{union semun su;su.val = value;if(semctl(sem_id,semnum,SETVAL,su) < 0){perror("semctl");exit(1);}
}
//初始化所有信号灯
void sem_init_all(int sem_id,unsigned short vals[])
{union semun su;su.array = vals;if(semctl(sem_id,0,SETALL,su) < 0){perror("semctl");exit(1);}
}
总结
本篇文章针对进程间通信system V IPC对象进行详细讲解,希望能够帮到大家!
以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!
希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!
相关文章:
C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)
目录 前言 一、system V IPC对象图解 1.流程图解: 编辑 2.查看linux内核中的ipc对象: 二、消息队列 1.消息队列的原理 2.消息队列相关的API 2.1 获取或创建消息队列(msgget) 实例代码如下: 2.2 发送消息到消…...
python—如何提取word中指定内容
假设有一个Word,该Word中存在 “联系人” 关键字,如何将该Word中的联系人所对应的内容提取出来呢? 该Word内容如下所示: 要在给定的Word文档中提取出与"联系人"关键字对应的内容,可以使用Python的py…...
分享几个通用个人简历模板|行业通用
Home(https://cvjury.com/) 专业设计的简历模板。 在竞争激烈的就业市场中脱颖而出的有效策略。 侧重于向招聘人员传达独特的价值主张。 帮助创建引人注目的简历、求职信和LinkedIn资料。 面向毕业生和学生的个性化简历解决方案。 添加图片注释,不超过 140 字&…...
如何正确操作封箱机
前文跟大家分享过封箱机错误操作三案例,那么封箱机到底如何才能正确操作呢?今天就和您分享一下如何正确操作封箱机。 1、确定正确的电源电压进行接入。目前国内封箱机均采用220v 50hz电源电压,但也有一些定制型设备可能使用380v电源ÿ…...
mysql面试题7:MySQL事务原理是什么?MySQL事务的隔离级别有哪些?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL事务原理是什么? MySQL事务的原理是基于ACID(原子性、一致性、隔离性、持久性)特性来实现的,具体原理如下: Atomicity(原子性):事务…...
vue 项目打包性能分析插件 webpack-bundle-analyzer
webpack-bundle-analyzer 是 webpack 的插件,需要配合 webpack 和 webpack-cli 一起使用。这个插件可以读取输出文件夹(通常是 dist)中的 stats.json 文件,把该文件可视化展现,生成代码分析报告,可以直观地…...
C++ day2
1->x.mind 2->...
【Kafka专题】Kafka集群架构设计原理详解
目录 前言前置知识课程内容一、Kafka的Zookeeper元数据梳理1.1 zookeeper整体数据1.2 Controller Broker选举机制1.3 Leader Partition选举机制1.4 Leader Partition自动平衡机制*1.5 Partition故障恢复机制1.6 HW一致性保障-Epoch更新机制1.7 总结 学习总结感谢 前言 Kafka的…...
Docker 镜像的缓存特性
Author:rab 目录 前言一、构建缓存二、Pull 缓存总结 前言 首先我们要清楚,Docker 的镜像结构是分层的,镜像本身是只读的(不管任何一层),当我们基于某镜像运行一个容器时,会有一个新的可写层被…...
Javascript 笔记:object
一部分object可以见:JavaScript 笔记 初识JavaScript(变量)_UQI-LIUWJ的博客-CSDN博客 1 in操作符 2 hasOwnProperty 3 获取一个object所拥有的所有property 不去原型链上找 4 定义data property...
【vue3】可编辑el-table
<template><el-table:data"tableData"style"width: 100%"><el-table-columnprop"date"label"日期"width"180"><template #default"{row,$index}"><input type"text" v-mode…...
一个开源的安卓相机:OpenCamera
原网址 Open Camera download | SourceForge.net 我也上传了一个 https://github.com/quantum6/Android-OpenCamera...
分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测
分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测 目录 分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测࿰…...
学习网络编程No.7【应用层之序列化和反序列化】
引言: 北京时间:2023/9/14/19:13,下午刚刚更完文章,是一篇很久很久以前的文章,由于各种原因,留到了今天更新,非常惭愧呀!目前在上学校开的一门网络课程,学校的课听不了一…...
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式 专栏介绍专栏地址专栏介绍 原型模式角色分类抽象原型(Prototype)具体原型(Concrete Prototype)客户端(Client)原型管理器(Prototype Manager…...
用《斗破苍穹》的视角打开C#3 标签与反射(人物创建与斗技使用)
随着剧情的发展,主线人物登场得越来越多,时不时跳出一个大佬,对我张牙舞爪地攻击。眼花缭乱的斗技让我不厌其烦,一个不小心,我就记不清楚在哪里遇上过什么人,他会什么斗技了。这时候,我就特别希…...
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些&#x…...
一文看懂光模块的工作原理
你们好,我的网工朋友 光模块有很多类别,是我们经常要用到的PHY层器件。虽然封装,速率,传输距离有所不同,但是其内部组成基本是一致的。 以太网交换机常用的光模块有SFP,GBIC,XFP,X…...
基于SpringBoot的桂林旅游景点导游平台
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 景点类型管理 景点信息管理 线路推荐管理 用户注册 线路推荐 论坛交流 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...
【小程序 - 加强】自定义组件、使用npm包、全局数据共享、分包_05
目录 一、自定义组件 1. 组件的创建与引用 1.1 创建组件 1.2 引用组件 1.2.1 局部引用组件 1.2.2 全局引用组件 1.2.3 全局引用 VS 局部引用 1.2.4 组件和页面的区别 2. 样式 2.1 组件样式隔离 2.2 组件样式隔离的注意点 2.3 修改组件的样式隔离选项 2.4 styleIso…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
