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

【Linux进程】进程间通信(共享内存、消息队列、信号量)

 

目录

前言

1. System V IPC

2. 共享内存

系统调用接口

shmget

 ftok

 shmat

 shmdt

shmctl

共享内存的读写

共享内存的描述对象

3. 消息队列

msgget

msgsnd

 msgctl

 消息队列描述对象

4. 信号量

 系统调用接口

 semget

semctl

信号量描述对象 

5. 系统层面IPC资源

6. 补充

总结


前言

        前边学习了管道通信,本文再来聊一聊其他的进程间通信方式:共享内存、消息队列、信号量;

在这里插入图片描述

1. System V IPC

        System V IPC(Inter-Process Communication)是 Unix 操作系统的一种进程间通信机制。它提供了一组系统调用,允许不同进程之间共享数据和信息;主要有三种通信方式:共享内存、消息队列、信号量;通常用于需要高效数据交换和同步的应用场景;

2. 共享内存

 ·        前边提到的的两种管道都可以实现进程之间单向通信,但对于一些数据量大且需要频繁传输数据时效率就显得有点低,为了满足需求,并统一标准,于是便出现共享内存这一通信标准;
        共享内存作为一种进程间通信的标准,主要是为了解决管道通信在大数据量和频繁传输数据时效率较低的问题。共享内存允许多个进程共享同一块内存区域,进程可以直接访问内存中的数据,避免了数据的复制和传输开销,从而提高了通信的效率;
        共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据;

进程间通信的前提:让不同的进程看到同一份资源(由操作系统提供);

 

操作系统只允许两个进程使用共享内存通信吗?

        肯定不是,操作系统允许系统中同时存在多个共享内存对于创建的多个共享内存当然也需要进行管理;先描述,再组织;存在一个struct shm的结构体;用于对共享内存的描述;(共享内存对象)每个新建的共享内存都有一个结构体描述对象,这样对多个共享内存的管理,就转换成了对结构体对象的管理;

构建信道:

  1. 创建共享内存区域。
  2. 将共享内存映射到进程地址空间
  3. 进行通信

关闭信道:

  1. 解除共享内存映射
  2. 减少引用计数。
  3. 释放共享内存

问题来了,如何保证第二个参与通信的进程,找到的就是同一个共享内存呢?匿名管道可以通过父子进程继承的方式找到,命名管道可以通过文件系统找到,共享内存如何保证信道成功建立呢?
存在一个唯一的标识,进行识别

系统调用接口

shmget

shmget 用于创建一个新的共享内存段,或者获取一个已经存在的共享内存段的标识符;

 

 shmflg标志参数,目前只需了解两个:

  • IPC_CREAT:共享内存不存在就创建(创建后把标识符写到共享内存属性中),存在就获取与返回共享内存标识符
  • IPC_EXCL:不单独使用,一般与IPC_CREAT一起使用(IPC_EXCL | IPC CREAT):如果不存在就创建,如果存在就出错返回;主要用于确保创键的是一个新的共享内存;

 补充:

  • 共享内存(IPC资源)的生命周期是随内核的;
  • ipcrm -m 删除共享内存
  • ipcs -m查看存在的共享内存
  • shmid:共享内存id,使用这个共享内存时,我们一般使用shmid来进行操作共享内存
  • Key:一般不在应用层使用,只用来标识shm的唯一性;

 

 ftok

        前边我们提到如何让第二个进程找到共享内存,答案就是标识符,这里的key就是标识符;通信双方约定一个标识符,一方将标识符写入到共享内存对象中,另一方可以遍历进行查找标识符,就可以保证它们找到的是同一份资源;
        这里的标识符,理论上是可以随便写一个,只不过随便写的方式很容易与系统中已经存在的标识符冲突,所以一般会使用算法来生成唯一的标识符;这个接口就是ftok ;

         ftok()函数会使用指定的路径名和项目标识符来计算一个key值,该key值在系统中是唯一的,返回的key值可以作为参数传递给shmget()函数,从而指定共享内存段的标识符;

        pathname参数是一个指向以null结尾的路径名的指针。它的作用是为了生成一个唯一的key值。ftok()函数会使用指定的路径名来获取文件的inode号,然后将其与proj id参数合并,生成一个唯一的key值;
        这个路径名并不需要对应一个真实存在的文件,它只是用作生成key值的一个标识。通常情况下会选择一个在系统中唯一的、不会轻易更改的路径名来确保生成的key值是唯一的,以避免不同的进程之间出现key冲突;
        pathname参数要指向一个可靠的文件路径,比如一个特定的系统文件或者应用程序中的固定路径。这样可以确保在不同的系统中或者不同的程序中,使用相同的路径名生成的key值是相同的;

 shmat

shmat() 用于将共享内存段连接到调用进程的地址空间,形成一个虚拟地址的映射

 接口返回值void*返回共享内存在共享区映射的起始地址;

 shmdt

        shmdt 用于将共享内存段从进程的地址空间中分离,即解除该共享内存段与进程地址空间的映射关系
成功,shmdt()函数返回0;如果失败,返回-1,并设置errno来指示错误类型 ;

shmctl

 

shmctl控制共享内存段的函数,包含获取共享内存段信息、设置共享内存段的权限、删除共享内存段等;它的功能很多,当前我们主要使用删除的功能;

IPC RMID:删除共享内存段

 为什么我们使用标识符key需要使用者自己生成,为什么OS不直接自己生成?

        就是为了让使用者知道,然后好让目标进程通过这个值找到共享内存;如果让系统生成,使用者不知道标识符,那目标进程又如何知道这个标识符呢?内存中有多个共享内存,目标进程又如何去找自己的共享内存呢?根本不可能;要想找到共享内存就必须两进程提前约定好标识符,这样才能找到共享内存;

共享内存的读写

 共享内存在用户空间,如何控制读写呢?

在共享内存的开头或者结尾,留了一块区域,用来存储共享内存的属性,比如:读位置、写位置;

删除数据呢?和vector删除一样,不需要清空数据,只需要数据变无效即可;

特点:

  • 共享内存通信不提供同步机制,它是直接裸露给使用者的,所以一定要注意共享内存的使用安全问题;
  • 共享内存是所有进程通信速度最快的;
  • 共享内存可以提供较大的空间;

 为什么说共享内存是最快的通信方式?

对比一下管道:

进程A要想把数据通过管道发送给进程B,先从用户空间拷贝到管道(内核空间),进程B通过read把数据从管道再拷贝一份到自己的用户空间;

这里是很影响效率的具体分析一下:先把数据写到自定义的缓冲区,然后再把缓冲区的数据拷贝到内核空间的管道,读方再把数据从内核空间拷贝到自己定义的缓冲区;

 共享内存:

        进程A只要写入数据,就直接写入到了共享内存中,而进程B立马就能看到;共享内存的写入原理和malloc申请的空间使用类似,都是直接写入到内存中;不需要什么缓冲区,更不需要来回进行拷贝;共享内存不需要内核级别的拷贝,所以相对于管道来说效率更高,在应用场景中减少了拷贝的次数 ;

共享内存的描述对象

 以上是部分属性;

 

 编写一个简单的程序使用并验证一下:

 comm.hpp

#pragma once#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>const std::string pathname = "/home/test/test/share_memory";
const int proj_id = 0x11223344;
//共享内存的大小建议设置成4096的整数倍
const int size = 4096;
key_t Getkey()
{key_t k = ftok(pathname.c_str(), proj_id);//把字符串转化成C字符串风格if (k < 0){std::cerr << "error: " << errno << " errorstring: " << strerror(errno) << std::endl;exit(1);}//std::cout << "key: " << k << std::endl;return k;
}std::string ToHex(int id)
{char buffer[1024];snprintf(buffer, sizeof(buffer), "0x%x", id);return buffer;
}
int CreateShmHelper(key_t key, int flag)
{int shmid = shmget(key, size, flag);if (shmid < 0){std::cerr << "error: " << errno << " errorstring: " << strerror(errno) << std::endl;exit(2);}return shmid;
}int CreateShm(key_t key)
{return CreateShmHelper(key, IPC_CREAT | IPC_EXCL | 0664);
}int GetShm(key_t key)
{return CreateShmHelper(key, IPC_CREAT);
}

 test.cc

class Init
{
public:Init(){key_t key = Getkey();std::cout << "key: " << ToHex(key) << std::endl;shmid = CreateShm(key);// sleep(5);std::cout << "shmid: " << shmid << std::endl;std::cout << "开始将shm映射到进程的地址空间中" << std::endl;// sleep(5);s = (char*)shmat(shmid, nullptr, 0);// 打开管道用于发送信息进行控制,如果管道写端没有连接就一直阻塞// fd = open(filename.c_str(), O_RDONLY);}~Init(){shmdt(s);std::cout << "开始将shm从进程的地址空间中移除" << std::endl;// sleep(5);shmctl(shmid, IPC_RMID, nullptr);std::cout << "开始将shm从OS中删除" << std::endl;// sleep(10);// close(fd);// unlink(filename.c_str());}public:int shmid;int fd;char* s;
};int main(){Init init;//获取共享内存属性struct shmid_ds ds;shmctl(init.shmid,IPC_STAT, &ds);std::cout << ToHex(ds.shm_perm.__key) << std::endl;std::cout << ds.shm_segsz << std::endl;std::cout << ds.shm_atime << std::endl;std::cout << ds.shm_nattch << std::endl;
}

 使用命令查看:

 这也就验证了之前所提到的共享内存对象,共享内存 = 共享内存空间 +共享内存属性

3. 消息队列

 消息队列:提供一个进程给另一个进程发送数据块的能力;

结构:

        消息队列是OS中维护的一个数据结构当一个进程想要把数据发送给另一个进程,就可以把数据块连接在消息队列上,成为消息队列的一个节点;

msgget

msgget接口可以用于获取已经存在的消息队列的标识符,还可以用于创建新的消息队列;

key需要在用户层进行设置,并且这个key可以被A进程看到,也可以被B进程看到还要写到消息队列的属性中;和shmget中的类似;

msgflg也是一样的,示例:

int msgid = msgget(key, IPC_CREAT | IPC_EXCL);

这个队列中,不仅A进程可以加入数据块,B进程也可以;这时就产生了新的问题:它们如何知道哪个是自己想要的节点?


为了分辨出哪个是节点是进程需要的,所以队列中的数据块需要有类型;

msgsnd

 发送消息

 消息节点:

 

 使用示例:

struct msgbuf {  long mtype;        // 消息类型  char mtext[256];   // 消息内容  
};int msgid = msgget(key, IPC_CREAT | 0666);// 填充内容
struct msgbuf message;  
message.mtype = 1; // 设置消息类别  
snprintf(message.mtext, sizeof(message.mtext), "Hello, World!");  
msgsnd(msgid, &message, strlen(message.mtext) + 1, 0)

 msgctl

这里依然和shmctl的接口很类似,当前主要使用它的删除功能(删除消息队列)

 使用示例:

msgctl(msgid, IPC_RMID, nullptr); // 删除消息队列
msgctl(msgid, IPC_STAT, &ds); // 获取消息队列状态

         消息队列的属性和接口,根共享内存都是十分相似;在系统中,也是允许同时有多个消息队列存在的;所以在内核中也需要把消息队列管理起来;先描述,再组织;消息队列 =队列 +队列属性

 消息队列描述对象

 也有一个 struct ipc_perm类型的对象;

消息队列中的struct_ipc_perm 和共享内存中的struct ipc_perm两个其实是完全一样的用于记录该对象的权限、拥有者、访问权限等信息;

4. 信号量

 如何理解信号量?信号量本质其实就是一个计数器;作用:用来保护共享资源

 举个例子:
        比如:看电影,我们去电影院看电影,去看之前需要先买票,是买到票后,指定的座位属于你,还是坐到座位上后座位才属于你?(排除没素质的情况)当然是买完票以后,那个座位就属于你了;

        电影院和座位就是多人共享公共资源;买票的本质就是对资源的预定!电影院中有固定的座位,那么在购票系统中就会存在一个计数器,用于记录剩下的座位数;如果买票成功计数器就减减;而这里的座位和电影院就是OS公共资源,每个人就是进程;而购票系统的计数器就是信号量;规定好信号量初始值,就可以控制访问资源的进程数量;

信号量:表示资源数目的计数器,每个执行流(进程)想要访问公共资源内的某一份资源,不能让执行流直接访问,而是应该先申请信号量资源,本质就是对信号量计数器做--操作。只要--成功就完成了对资源的预定机制;
如果申请不成功?执行流就会被挂起

         访问公共资源的代码执行前,先申请信号量,如果申请成功才让访问,申请失败就挂起阻塞;这样就形成了保护机制;

        当信号量的数值设为1;int sem = 1;这时就只允许一个执行流读取公共资源;执行流在读取时,其他执行流只能阻塞等待 sem 就只有两种状态:1、0;二元信号量---互斥锁---完成互斥功能;

         信号量存在的本质就是为了保护公共资源,信号量是公共资源,那谁来保护信号量?信号量都没法保护,那又怎么保护其他公共资源?
但好在信号量公共资源内容较为简单,申请时只需要--操作,--操作只要符合原子性就可以;也就是说要么申请完成,要么不申请;不存在其他情况;这样就避免了出现其他情况;

申请信号量的操作 —P

释放信号量的操作—V 

细节分析:

  1. 信号量是公共资源的计数器,那么就需要先让所有进程都能看到信号量资源 —— 只能由操作系统提供——纳入到IPC体系;
  2. 信号量本质也是公共资源

 对信号量管理的理解

// 单个信号量
{struct sem;int count;struct task struct *wait queue;
}

 系统调用接口

 semget

 nsems表示要创建的几个信号量;其余两个参数和shmget一样的;

示例:

int semid = semget(key, n, IPC_CREAT | 0666); // 创建一个信号量 0666 是读写权限
// n表示创建信号量的个数

 system V 允许创建一批(至少一个)信号量;如何支持创建一批?在创建时设置n(创建个数)

semctl

创建了信号量,如何设置信号量的计数?使用 semctl 函数来实现;

 示例:

// 设置信号量的值为初始值  
// 初始化计数为1
// 0 表示您要设置第一个信号量的值
semctl(semid, 0, SETVAL, 1);

 设置一组信号量呢?

 int initial_values[] = {1, 1, 1}; // 假设每个信号量的初始值为 1  for (int i = 0; i < num_semaphores; i++) {  semctl(semid, i, SETVAL, initial_values[i]) {}  

 当然也可以删除信号量:

semctl(semid, 0, IPC_RMID)

信号量描述对象 

 

         信号量允许存在多个,那么就需要对其进行管理,那么自然也有信号量描述对象;发现他也有struct ipc_perm对象;

5. 系统层面IPC资源

站在OS角度,内核是如何看待ICP资源的?它是OS内单独设计的模块
        共享内存、消息队列、信号量,它们在自己的描述对象开始都有一个ipc_perm 结构体通过对这个结构体的管理就可以达到对这三种IPC资源的管理 ;

 回顾一下柔性数组:

 kern_ipc_perm跟共享内存、消息队列以及信号量中的ipc_perm的内容一致,可以把它们看待成同一个结构体;

        统一使用该数组实现对IPC资源的管理,遍历这个数组,就可以通过 key 来判断某个IPC资源是否存在;

        数组中存放的是各种IPC资源的struct ipc_perm 结构体对象地址,每当需要增加一个IPC对象(共享内存、消息队列、信号量)时,就只需在数组中新增一个struct ipc_perm对象地址即可;

比如:想要访问共享内存对象中除struct ipc_perm 外的其他资源怎么办?直接使用*p肯定不行;只需要强转一下类型就可以;比如:p[1]存放的是消息队列的ipc_perm 

((msg_queue*)p[1])->...

把struct ipc perm*类型的指针强转成消息队列对象类型的指针,这样就可以访问了; 

这个设计模式很类似于多态;通过对相同类型的对象访问,就可以实现对不同IPC资源的管理 ;

想要更深入的了解可以拜读参考这篇文章:进程间通信:共享内存和信号量的统一封装机制原理与实现

6. 补充

进程间通信流程:

进程间通信 -->多个执行流看到同一份资源(公共资源) --> 并发访问 --> 数据干扰问题 --> 保护数据
--> 同步和互斥;

  • 互斥:任何时刻只允许一个执行流(进程)访问公共资源,比如:管道,只允许一个读一个写;互斥可以通过加锁完成;
  • 同步:多个执行流执行时按照一定顺序执行 ;

被保护起来的公共资源--临界资源;

访问临界资源的代码,被称为临界区;


总结

         好了以上便是本文的全部内容,希望对你有所帮助或启发,感谢阅读!

相关文章:

【Linux进程】进程间通信(共享内存、消息队列、信号量)

目录 前言 1. System V IPC 2. 共享内存 系统调用接口 shmget ftok shmat shmdt shmctl 共享内存的读写 共享内存的描述对象 3. 消息队列 msgget msgsnd msgctl 消息队列描述对象 4. 信号量 系统调用接口 semget semctl 信号量描述对象 5. 系统层面IPC资源 6.…...

负载均衡的原理

负载均衡&#xff08;Load Balancing&#xff09;是一种计算机技术&#xff0c;用于在多个服务器、网络连接、计算资源之间合理分配工作负载&#xff0c;以提升应用程序的可用性、性能和可扩展性&#xff0c;以下是详细介绍&#xff1a; 工作原理 流量分配&#xff1a;负载均衡…...

Flash Attention

op融合 原始方法&#xff1a; 痛点&#xff1a;多次读取、写入显存。 解决&#xff1a;中间结果不保存&#xff0c;1个kernel顺序算完多个操作。 反向传播时用到这些中间结果要求导&#xff0c;怎么办&#xff1f; 答&#xff1a;类似activation checkpointing&#xff0c;重新…...

Craft CMS 模板注入导致 Rce漏洞复现(CVE-2024-56145)(附脚本)

0x01 产品描述: ‌Craft CMS‌ 是一个灵活且强大的内容管理系统(CMS),专为创意团队和开发人员设计,提供高度可定制、直观且性能优越的网站和内容管理解决方案。它以用户友好的界面、强大的插件生态系统以及支持现代web开发最佳实践的特性而闻名‌0x02 漏洞描述: 由于模板…...

步进电机位置速度双环控制实现

步进电机位置速度双环控制实现 野火stm32电机教学 提高部分-第11讲 步进电机位置速度双环控制实现(1)_哔哩哔哩_bilibili PID模型 位置环作为外环,速度环作为内环。设定目标位置和实际转轴位置的位置偏差,经过位置PID获得位置期望,然后讲位置期望(位置变化反映了转轴的速…...

Sigrity Optimize PI CapGen仿真教程文件路径

为了方便读者能够快速上手和学会Sigrity Optimize PI和 Deacap Generate 的功能&#xff0c;将Sigrity Optimize PI CapGen仿真教程专栏所有文章对应的实例文件上传至以下路径 https://download.csdn.net/download/weixin_54787054/90171471?spm1001.2014.3001.5503...

open Feign日志输出

openFeign默认是没有日志输出的&#xff0c;只有在open Feign所在的包的级别达到debug才会有输出&#xff0c;而且级别有四级。 四种日志级别&#xff1a; OpenFeign只会在FeignClient所在包的日志级别为DEBUG时&#xff0c;才会输出日志。而且其日志级别有4级&#xff1a; NON…...

进程间关系与守护进程

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 进程间关系与守护进程 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 进程组 什…...

C++设计模式:组合模式(公司架构案例)

组合模式是一种非常有用的设计模式&#xff0c;用于解决**“部分-整体”**问题。它允许我们用树形结构来表示对象的层次结构&#xff0c;并且让客户端可以统一地操作单个对象和组合对象。 组合模式的核心思想 什么是组合模式&#xff1f; 组合模式的目的是将对象组织成树形结…...

ubuntu 安装docker

Step1&#xff1a;更新系统软件包 sudo apt update Step2&#xff1a;安装依赖包【用于通过HTTPS来获取仓库】 sudo apt install apt-transport-https ca-certificates curl software-properties-common Step3&#xff1a;添加Docker官方GPG密钥 sudo -i curl -fsSL https://…...

PSDK的编译与ROS包封装

本文档讲述在NIVIDIA开发板上使用大疆提供的Payload SDK获取无人机实时GPS信息的方法&#xff0c;以及基于Payload SDK发布ROS GPS话题信息的方法。 文章目录 0 实现目标1 Payload SDK1.1 PSDK 源码的编译1.2 PSDK 的使用 2 遥测数据的读取2.1 示例代码结构2.2 读取机载GPS信息…...

【工作流】工作顺序

背景 当时的情况是&#xff1a;没有产品经理&#xff0c;后端直接和需求方对接&#xff1b;前端只能短时间投入大部分时间要忙别的&#xff1b;只有3个角色&#xff1a;需求方&#xff0c;后端&#xff0c;前端&#xff1b; 当时直接执行的 直接使用会议了解需求&#xff0c…...

Unity2021.3.16f1可以正常打开,但是Unity2017.3.0f3却常常打开闪退或者Unity2017编辑器运行起来就闪退掉

遇到问题&#xff1a; 从今年开始&#xff0c;不知道咋回事&#xff0c;电脑上的Unity2017像是变了个人似得&#xff0c;突然特别爱闪退掉&#xff0c;有时候还次次闪退&#xff0c;真是让人无语&#xff0c;一直以来我都怀疑是不是电脑上安装了什么别的软件了&#xff0c;导致…...

Java基础面试题20:Java语言sendRedirect()和forward()方法有什么区别?

Java基础面试题&#xff1a;Java语言sendRedirect()和forward()方法有什么区别&#xff1f; 在 Java Web 开发中&#xff0c;sendRedirect() 和 forward() 是两个非常常用的方法&#xff0c;但它们有一些核心区别。我们来用最简单的方式给你解释清楚。 一、sendRedirect() 和 …...

2、光同步数字传送网的特点

同步复用 光同步数字传送网&#xff08;SDH&#xff09;采用同步复用方式。它将多个低速信号复用成高速信号&#xff0c;与准同步数字体系&#xff08;PDH&#xff09;的异步复用不同。在 SDH 中&#xff0c;各支路信号与复用后的高速信号是同步的&#xff0c;这种同步复用的方…...

3.4 stm32系列:定时器(PWM、定时中断)

一、定时器概述 1.1 软件定时原理 使用纯软件&#xff08;CPU死等&#xff09;的方式实现定时&#xff08;延时&#xff09;功能&#xff1b; 不精准的延迟&#xff1a; /* 微秒级延迟函数* 不精准* stm32存在压出栈过程需要消耗时间* 存在流水线&#xff0c;执行时间不确定…...

【环境搭建】Python、PyTorch与cuda的版本对应表

一个愿意伫立在巨人肩膀上的农民...... 在深度学习的世界里&#xff0c;选择合适的工具版本是项目成功的关键。CUDA、PyTorch和Python作为深度学习的三大支柱&#xff0c;它们的版本匹配问题不容忽视。错误的版本组合可能导致兼容性问题、性能下降甚至项目失败。因此&#xff0…...

【经验总结】AUTOSAR架构下基于TJA1145收发器偶发通信丢失不可恢复问题分析

目录 前言 正文 1.问题描述 2.尝试问题复现 3.尝试问题定位 4.直接原因 5.总结 前言 在《【CAN通信】TJA1145收发器重要功能介绍》一文中我们详细介绍了TJA1145收发器的重点内容,最近在开发测试过程中就遇到了一个CAN通信丢失且不可恢复的偶发问题,解决该问题的思路和…...

帝国CMS:如何去掉帝国CMS登录界面的认证码登录

如果在安装的时候&#xff0c;不小心选中了认证码选项&#xff0c;那么后面登录帝国后台都会要求输入认证码才能登录&#xff0c;如何去除这个设置呢&#xff0c;笔者以古诗词网 www.gushichi.com为例&#xff0c;为大家举例说明&#xff01; 去除步骤如下&#xff1a; 1.前往…...

CTF入门:单主机渗透——flag_XEE的常规思路

学习通过技术手段获取目标主机中预置的5个flag值。 在kali操作机中打开终端&#xff0c;然后使用nmap工具对目标机器进行端口扫描&#xff1a; nmap -sT 192.168.12.26 访问80端口。 网站首页是一个登录框&#xff0c;在界面上有一个提示的标签“弱口令”&#xff0c;说…...

Note2024122303_Code2Docu插件使用

Note2024122303_Code2Docu插件初使用V1.0 step1: 安装 跳转链接 文档阅读&#xff1a;下载文档阅读。 根据文档内容&#xff0c;大概知道首先下载并安装插件&#xff1a; 资料说明和安装方式&#xff1a; 意思是&#xff1a; 下载文件后直接运行 Code2Docu_Installati…...

深度学习之目标检测篇——残差网络与FPN结合

特征金字塔多尺度融合特征金字塔的网络原理 这里是基于resnet网络与Fpn做的结合&#xff0c;主要把resnet中的特征层利用FPN的思想一起结合&#xff0c;实现resnet_fpn。增强目标检测backone的有效性。代码实现如下&#xff1a; import torch from torch import Tensor from c…...

共模电感的工作原理

共模电感也称为共模扼流线圈&#xff0c;是一种抑制共模干扰的器件&#xff0c;它是由两个尺寸相同&#xff0c;匝数相同的线圈对称地绕制在同一个铁氧体环形磁芯上&#xff0c;形成的一个四端器件。当共模电流流过共模电感时&#xff0c;磁芯上的两个线圈产生的磁通相互叠加&a…...

mysql高阶语句

mysql高阶语句 1.对结果排序 SELECT id,name,score FROM info; #由于对id设置了主键约束&#xff0c;默认排序按id的大小升序排序 select name,score from info order by score; #默认按升序&#xff08;从小到大排序&#xff09; select name,score from info order by score…...

sfnt-pingpong -测试网络性能和延迟的工具

sfnt-pingpong 是一个用于测试网络性能和延迟的工具&#xff0c;通常用于测量不同网络环境下的数据包传输性能、吞吐量、延迟等指标。 它通常是基于某种网络协议&#xff08;如 TCP&#xff09;执行“ping-pong”式的测试&#xff0c;即客户端和服务器之间相互发送数据包&…...

PostgreSQL 的历史

title: PostgreSQL 的历史 date: 2024/12/23 updated: 2024/12/23 author: cmdragon excerpt: PostgreSQL 是一款功能强大且广泛使用的开源关系型数据库管理系统。其历史可以追溯到1986年,当时由加州大学伯克利分校的一个研究团队开发。文章将深入探讨 PostgreSQL 的起源、…...

【express-generator】01-安装和基本使用

创建和初始化项目 安装 npm i -g express-generator 创建一个express应用程序 //express 文件名 express blog_demo 跟着提示 cd blog_demo //移动到该目录下 npm install //初始化 npm start //启动服务 在页面打开localhost:3000&#xff08;默认启动的端口&#xff09…...

20241230 基础数学-线性代数-(1)求解特征值(numpy, scipy)

所有代码实现&#xff0c;基于教程中的理论通过python实现出来的。效率不高&#xff0c;但有代码可以看。 由于scipy/sckitlearn/sparkx 底层的实现都被封装了&#xff08;小白兔水平有限&#xff0c;fortran代码实在没看懂&#xff09;这里的实现至少可以和理论公式对应的上。…...

无人零售 4G 工业无线路由器赋能自助贩卖机高效运营

工业4G路由器为运营商赋予 “千里眼”&#xff0c;实现对贩卖机销售、库存、设备状态的远程精准监控&#xff0c;便于及时补货与维护&#xff1b;凭借强大的数据实时传输&#xff0c;助力深度洞察销售趋势、优化库存、挖掘商机&#xff1b;还能远程升级、保障交易安全、快速处理…...

python+opencv+棋盘格实现相机标定及相对位姿估计

pythonopencv棋盘格实现相机标定及相对位姿估计 引言1&#xff0c;使用相机采集含棋盘格图像14张2&#xff0c;进行相机标定&#xff08;1&#xff09;测试软件1标定结果&#xff08;内参及畸变系数&#xff09;&#xff08;2&#xff09;测试软件2标定结果&#xff08;内参及畸…...

【YashanDB知识库】in大量参数时查询性能慢

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7802939.html?templateId1718516 **【标题】**in大量参数时查询性能慢 **【关键字】**in 大量参数 FAST FULL SCAN INDEX RANGE SCAN **【问题描述】**测试表数据量200w&#xff0c;表…...

kubevirt网络

六、KubeVirt网络 KubeVirt网络相关组件 用户在KubeVirt平台创建虚拟机只需创建一个vmi&#xff08;Virtual Machine Instance&#xff09;对象&#xff0c;之后virt-controller会根据vmi对象中的信息创建一个Pod&#xff0c;这里把这个Pod叫做vmi pod。Vmi pod中有kubevirt组…...

LeetCode100之腐烂的橘子(994)--Java

1.问题描述 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单元…...

【Leetcode】855. 考场就座

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 在考场里&#xff0c;有 n n n 个座位排成一行&#xff0c;编号为 0 0 0 到 n − 1 n - 1 n−1。 当学生进入考场后&#xff0c;他必须坐在离最近的人最远的座位上。如果有多个…...

AI,cursor快速上手思维导图

https://cursor101.com/zh/tutorial/learn-cursor-tab...

【演化博弈】期望收益函数公式、复制动态方程——化简功能技巧

期望化简 在演化博弈论的研究中&#xff0c;期望收益函数和复制动态方程是核心工具。化简这些公式的功能技巧具有以下几个重要作用&#xff1a; 提高公式的可读性和理解度 复杂的数学表达式可能让人感到困惑。通过化简&#xff0c;公式变得更加简单和易读&#xff0c;使研究者…...

常用Linux命令

常用Linux命令介绍 1.ls命令用于列出当前目录的内容&#xff0c;包括目录、文件和压缩包等。 2.ls命令的参数可以以长格式显示文件信息&#xff0c;如修改时间、文件大小等。 3.使用ls -a参数可以显示隐藏文件和文件夹。 4.通过ls -lh命令可以以人类可读的方式显示文件和文件夹…...

记录树莓派4B安装向日葵的过程

到向日葵官网下载向日葵 for Linux的麒麟Arm64版本&#xff1b;sudo dpkg -i 文件名.deb 安装&#xff1b;安装依赖&#xff1a; sudo apt install libappindicator3-1 如果没有的话就使用&#xff1a; sudo apt install libayatana-appindicator3-1 关闭wayvnc服务及其自启动…...

模型 课题分离

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。明确自我与他人责任。 1 课题分离的应用 1.1课题分离在心理治疗中的应用案例&#xff1a;李晓的故事 李晓&#xff0c;一位28岁的软件工程师&#xff0c;在北京打拼。他面临着工作、家庭和感情的多重…...

docker部署微信小程序自动构建发布和更新

通过 Jenkins 和 Docker 部署微信小程序&#xff0c;并实现自动构建、发布和版本更新&#xff0c;主要涉及以下几个步骤&#xff1a; 设置 Jenkins 环境配置 GitLab 与 Jenkins 的集成构建 Docker 镜像部署和发布微信小程序配置 Jenkins 自动构建 以下是详细的步骤说明&#…...

0.96寸OLED显示屏详解

我们之前讲了 LCD1602&#xff0c;今天我们将它的进阶模块——OLED。它接线更少&#xff0c;性能更强&#xff0c;也能显示中文和图像了。 大家在学习单片机的时候是否会遇到调试的问题呢&#xff1f;例如 “这串代码我到底运行成功了没有” &#xff0c;我相信很多刚开始学习…...

【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】

本教程的知识点为&#xff1a;操作系统 1. 常见的操作系统 4. 小结 ls命令选项 2. 小结 mkdir和rm命令选项 1. mkdir命令选项 压缩和解压缩命令 1. 压缩格式的介绍 2. tar命令及选项的使用 3. zip和unzip命令及选项的使用 4. 小结 编辑器 vim 1. vim 的介绍 2. vim 的工作模式 …...

H3C AC_AP基本配置流程

前置摘要 AP管理地址:10.115.8.0/ AP业务地址:10.115.10.0 SSID qdtest passwd 123chery map.txt system-view vlan 1010 quit interface GigabitEthernet 1/0/1 port link-type trunk port trunk permit vlan 1010AC配置 vlan 1008 des Ap_manager quit int vlan 1008 ip ad…...

准备写一个内网穿透的工具

准备写一个内网穿透的工具&#xff0c;目前只实现了HTTP内网穿透的GET方式&#xff0c;看能不能坚持写下去 git地址&#xff1a; xuejiazhi/PortRelay...

模型高效微调方式

除了LoRA&#xff08;Low-Rank Adaptation&#xff09;外&#xff0c;还有其他一些快速且效果好的模型微调方法。这些方法可以在保持模型性能的同时&#xff0c;减少计算和存储需求。以下是几种常见的方法&#xff1a; 1. 参数高效微调&#xff08;Parameter-Efficient Fine-T…...

Linux系统编程——理解系统内核中的信号捕获

目录 一、sigaction() 使用 信号捕捉技巧 二、可重入函数 三、volatile关键字 四、SIGCHLD信号 在信号这一篇中我们已经学习到了一种信号捕捉的调用接口&#xff1a;signal(),为了深入理解操作系统内核中的信号捕获机制&#xff0c;我们今天再来看一个接口&#xff1a;si…...

ISP算法之BNR降噪(Bayer域)

概述 BNR&#xff08;Bayer Noise Reduction&#xff09;即Bayer域降噪算法。对于噪声的分类如下表所示&#xff1a; 高斯噪声&#xff08; Gaussian&#xff09; 高斯噪声也被称为热噪声&#xff0c;通常是由于电路系统中自由电子的热运动&#xff0c;这种噪声幅度分布服从高…...

HBuilder快捷键大全

目录 一、最常用快捷键 二、文件操作快捷键 三、选择操作快捷键 四、插入操作快捷键 五、编辑操作快捷键 六、删除操作快捷键 七、查找操作快捷键 八、标签规范快捷键 八、运行操作快捷键 九、转换操作快捷键 十、跳转操作快捷键 十一、附加功能快捷键 十二、快捷键…...

Diffusion_Policy项目测试报错记录

1、项目连接 paper&#xff1a;2303.04137 (arxiv.org) github: real-stanford/diffusion_policy: [RSS 2023] Diffusion Policy Visuomotor Policy Learning via Action Diffusion (github.com) 2、问题与解决办法 1&#xff09; 运行 python train.py --..... 显示无法Err…...

Linux内核学习资源

老版本内核源码&#xff1a; https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/old-versions/ 内核源码分析开源项目&#xff1a; https://github.com/ultraji/linux-0.12/tree/master/srchttps://gitee.com/wslyx/linux-0.12https://github.com/0voice/linux_ke…...