Linux:进程间通信->匿名管道实现内存池
1. 进程间通信
(1) 概念
进程间通信(IPC) 就是不同进程间交换数据的方法,进程间是独立的所以不能访问彼此的内存,需要某种机制来通信(管道、消息队列,共享内存等)
(2) 目的
数据传输:一个进程需要他的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源
通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件(例如子进程终止通知父进程)
进程控制:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并及时知道它的状态改变
(3) 本质
让不同的进程先看到同一份资源(内存) 才有通信的条件。 同一份资源由操作系统OS来提供系统调用,OS的接口->设计统一的通信接口。
2. 匿名管道
管道是Unix中进程通信的形式,把一个进程链接到另一个进程的数据流称为一个管道.
匿名管道是单向通信:一端写另一端读。用于做父子通信,通过对文件的读写来实现通信,通过文件描述符表来实现fd。
使用原理是创建一个子进程,让父子进程都指向一个文件,最后我们就可以让父进程写入或读取,子进程读取或写入数据了。
创建匿名管道
#include <unistd.h>
int fd[2];
pipe(fd);
pipe系统调用,创建匿名管道,fd数组存储两个文件描述符
所需头文件<unistd.h>
fd[0]:读端(从管道文件读取数据)
fd[1]:写端(向管道文件写入数据)
匿名管道的五种特性
- 只能用来进行具有血缘关系的进程间通信(常用于父与子)
- 管道文件自带同步机制 快的等待慢的
- 管道是面向字节流的
- 管道是单向通信的(特殊的半双工)
- 管道文件的生命周期是随进程的(所有拥有其读写端fd的都close关闭)进程终止时,所有未关闭的fd都会被内核自动关闭。
四种通信情况
- 写慢,读快---读端就要阻塞(等待写端写入)。
- 写快,读慢---满了的时候,写就要阻塞等待
- 写关闭,读继续---read就会读到返回值为0,表示文件结尾
- 读关闭,写继续---写端再写入也没有任何意义了
操作系统OS不做无意义的事情,OS会(发送异常信号)杀掉写端进程
3. 进程池实现
三个类来描述再组织
channel
描述这个管道
class Channel
{
public:Channel(int wfd, pid_t chpid): _wfd(wfd),_chpid(chpid){// to_string 将数字转化为string形式_name = "channel-" + std::to_string(_wfd) + "+" + std::to_string(_chpid);}int Fd() { return _wfd; } // 返回_wfdpid_t Chpid() { return _chpid; } //..std::string Name() { return _name; } // 返回名字void Send(int code){int n= write(_wfd,&code,sizeof code);(void)n;//调用一下n,防止检查}void Close(){close(_wfd);}void Wait(){pid_t rid=waitpid(_chpid,nullptr,0);(void)rid;//操作一下这个变量}~Channel() {}private:int _wfd; // 文件描述符pid_t _chpid; // 对应的子进程是谁std::string _name; // 命名信道方便区分
};
Senf写入任务码
Close关闭写端fd
Wait等待子进程
ChannelManage
用来管理创建的匿名管道
// 管理Channel管道
class ChannelManage
{
public:ChannelManage(){}void InsterChannel(int wfd, pid_t chpid) // 写的fd 与子进程pid{// Channel c(wfd,chpid);// _channel.push_back(std::move(c));_channel.emplace_back(wfd, chpid); // 免去拷贝}void PrintfChannel(){for (auto &channel : _channel){std::cout << channel.Name() << std::endl;}}Channel& Select(){auto& c=_channel[_next];_next++;if(_next==_channel.size())_next=0;return c;}// void StopSubprocess()//暂停子进程// {// for(auto& channel:_channel)// {// channel.Close();//关闭接口// std::cout<<"关闭:"<<channel.Name()<<std::endl;// }// }// void WaitSubprocess()//等待子进程结束// {// for(auto& channel:_channel)// {// channel.Wait();//等待进程// std::cout<<"回收:"<<channel.Name()<<std::endl;// }// }void CloseAll(){for(auto& channel:_channel){channel.Close();//关闭父进程历史打开的写端// std::cout<<"关闭:"<<channel.Name()<<std::endl;}}void CloseAndWait(){//越早开辟的进程,写端引用计数的越多,关闭不了for(auto& channel:_channel){channel.Close();//关闭接口std::cout<<"关闭:"<<channel.Name()<<std::endl;channel.Wait();//等待进程std::cout<<"回收:"<<channel.Name()<<std::endl;}//解决方法1://倒着关闭所有进程// for(int i= _channel.size()-1;i>=0;i--)// {// _channel[i].Close();//关闭接口// std::cout<<"关闭:"<<_channel[i].Name()<<std::endl;// _channel[i].Wait();//等待进程// std::cout<<"回收:"<<_channel[i].Name()<<std::endl;// }//解决方案2://让父进程一个指向所有管道写端w}~ChannelManage(){}private:std::vector<Channel> _channel; // 存储管道int _next=0;
};
InsterChannel :插入新的匿名管道 写端fd 与 子进程的pid
PrintfChannel :输出所有匿名管道的名字
Select :按顺序返回管道
CloseAll :关闭父进程历史打开的写端,让写端基本不会重复打开
CloseAndWait :关闭写端,CloseAll用来解决写端引用计数过多无法关闭的情况。
Select的作用
干活不能只让一个人干,执行任务不能总让一个子进程去执行所以有三种方法
1. 轮询 2. 随机 3. Channel增添一个负载指标,通过这个指标来选择谁干活
这里Select采用了轮询的方式
TaskManager 与 ProcessPool
typedef void (*task_t)();//函数指针void PrintfLog()
{std::cout<<"我是打印日志的任务"<<std::endl;
}void Download()
{std::cout<<"我是下载文件的任务"<<std::endl;
}void Upload()
{std::cout<<"我是上传文件的任务"<<std::endl;
}class TaskManager
{
public:TaskManager(){srand(time(nullptr));}void Register(task_t t)//注册{_tasks.push_back(t);}int Code(){return rand()%_tasks.size();}void Execute(int code){if(code>=0&&code< _tasks.size())//在数组范围内{_tasks[code]();//根据传递来的任务码来执行任务}}~TaskManager(){}
private:std::vector<task_t> _tasks;
};
存储各种任务
class ProcessPool
{
public:ProcessPool(int num=5): _process_num(num){_tm.Register(PrintfLog);//将任务都存入_tm管理_tm.Register(Download);_tm.Register(Upload);}void Work(int rfd) // 读端文件描述符{while (true){int code=0;//最大读入长度为4,所以ssize_t n=read(rfd,&code,sizeof code);if(n > 0)//读成功{if(n!=sizeof code)//读取数据长度要为我们规定的长度{continue;//不然重新读}std::cout<<"子进程"<<getpid()<<"收到任务码,任务码为:"<<code<<std::endl;//要执行任务了_tm.Execute(code);//执行code这个任务}else if(n==0)//读到头了{std::cout<<"子进程退出"<<std::endl;break;}else//n<0 读取失败了{std::cout<<"读取数据失败"<<std::endl;break;// exit(1);}// std::cout << "我是子进程,我的rfd是" << rfd << std::endl;sleep(1);}}bool Create() // 初始化管道{for (int i = 0; i < _process_num; i++){// 创建匿名管道int pipefd[2] = {0};int n = pipe(pipefd);if (n < 0)return false; // 失败了// 创建子进程pid_t nid = fork();if (nid == 0) // 子进程负责读{//让子进程关闭自己继承下来的哥哥进程的写端关闭就可以了//只会影响引用计数不关闭父进程写端_cm.CloseAll();//写实拷贝所以不会影响父进程。子进程每次关闭都只关子进程的close(pipefd[1]); // 将写端关闭Work(pipefd[0]); // 读端工作close(pipefd[0]);exit(0); // 工作完就退出即可}else if (nid < 0) // 创建失败{std::cout << "子进程创建失败" << std::endl;return false;}else // 父进程{// char buf[1024];close(pipefd[0]); // 读端关闭_cm.InsterChannel(pipefd[1], nid); // 将这个子进程加入数组保存// close(pipefd[1]); // 写端关闭要在最后才关闭}}return true;}void Debug(){_cm.PrintfChannel();}void PushTask()//写任务{//不能选择一个子进程一直用啊//下面三种实现负载均衡方案//1. 轮询 2. 随机 3. Channel添加一个负载指标,通过是否达成指标来//1. 选一个任务int taskcode=_tm.Code();//随机选一个任务//2. 选择一个信道 子进程auto& c=_cm.Select();std::cout<<"选择了一个子进程"<<c.Name()<<std::endl;//3. 发送任务c.Send(taskcode);//传任务码std::cout<<"发送了一个任务码:"<<taskcode<<std::endl;}void Stop(){// //关闭父进程所有的wfd// _cm.StopSubprocess();// //回收所有子进程// _cm.WaitSubprocess();_cm.CloseAndWait();}~ProcessPool(){}private:ChannelManage _cm; // 管理所有的管道int _process_num; // 进程数量TaskManager _tm;//管理所有的任务
};
三个参数
ChannelManage _cm; // 管理所有的管道
int _process_num; // 记录进程数量
TaskManager _tm;//管理所有的任务
Create:pipe创建匿名管道,并将父子进程通过if else分开执行任务
Work :参数为读端文件描述符,所执行任务码通过read 来获得
PushTask :选择一个任务来执行通过轮询机制
Stop :关闭所有写端
4. 源码
processpol.hpp
hpp文件是一种在C++中的特殊头文件,通常用于将类的声明和实现放在同一个文件中。
.h文件和.cpp文件将类的声明和实现分离的方式不同,hpp文件将这两者结合在一起。
#pragma once
#include <cstdio>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <vector>
#include <string>
#include<sys/wait.h>
#include<sys/types.h>
#include "Task.hpp"
class Channel
{
public:Channel(int wfd, pid_t chpid): _wfd(wfd),_chpid(chpid){// to_string 将数字转化为string形式_name = "channel-" + std::to_string(_wfd) + "+" + std::to_string(_chpid);}int Fd() { return _wfd; } // 返回_wfdpid_t Chpid() { return _chpid; } //..std::string Name() { return _name; } // 返回名字void Send(int code){int n= write(_wfd,&code,sizeof code);(void)n;//调用一下n,防止检查}void Close(){close(_wfd);}void Wait(){pid_t rid=waitpid(_chpid,nullptr,0);(void)rid;//操作一下这个变量}~Channel() {}private:int _wfd; // 文件描述符pid_t _chpid; // 对应的子进程是谁std::string _name; // 命名信道方便区分
};// 管理Channel管道
class ChannelManage
{
public:ChannelManage(){}void InsterChannel(int wfd, pid_t chpid) // 写的fd 与子进程pid{// Channel c(wfd,chpid);// _channel.push_back(std::move(c));_channel.emplace_back(wfd, chpid); // 免去拷贝}void PrintfChannel(){for (auto &channel : _channel){std::cout << channel.Name() << std::endl;}}Channel& Select(){auto& c=_channel[_next];_next++;if(_next==_channel.size())_next=0;return c;}// void StopSubprocess()//暂停子进程// {// for(auto& channel:_channel)// {// channel.Close();//关闭接口// std::cout<<"关闭:"<<channel.Name()<<std::endl;// }// }// void WaitSubprocess()//等待子进程结束// {// for(auto& channel:_channel)// {// channel.Wait();//等待进程// std::cout<<"回收:"<<channel.Name()<<std::endl;// }// }void CloseAll(){for(auto& channel:_channel){channel.Close();//关闭父进程历史打开的写端// std::cout<<"关闭:"<<channel.Name()<<std::endl;}}void CloseAndWait(){//越早开辟的进程,写端引用计数的越多,关闭不了for(auto& channel:_channel){channel.Close();//关闭接口std::cout<<"关闭:"<<channel.Name()<<std::endl;channel.Wait();//等待进程std::cout<<"回收:"<<channel.Name()<<std::endl;}//解决方法1://倒着关闭所有进程// for(int i= _channel.size()-1;i>=0;i--)// {// _channel[i].Close();//关闭接口// std::cout<<"关闭:"<<_channel[i].Name()<<std::endl;// _channel[i].Wait();//等待进程// std::cout<<"回收:"<<_channel[i].Name()<<std::endl;// }//解决方案2://让父进程一个指向所有管道写端w}~ChannelManage(){}private:std::vector<Channel> _channel; // 存储管道int _next=0;
};class ProcessPool
{
public:ProcessPool(int num=5): _process_num(num){_tm.Register(PrintfLog);//将任务都存入_tm管理_tm.Register(Download);_tm.Register(Upload);}void Work(int rfd) // 读端文件描述符{while (true){int code=0;//最大读入长度为4,所以ssize_t n=read(rfd,&code,sizeof code);if(n > 0)//读成功{if(n!=sizeof code)//读取数据长度要为我们规定的长度{continue;//不然重新读}std::cout<<"子进程"<<getpid()<<"收到任务码,任务码为:"<<code<<std::endl;//要执行任务了_tm.Execute(code);//执行code这个任务}else if(n==0)//读到头了{std::cout<<"子进程退出"<<std::endl; break;}else//n<0 读取失败了{std::cout<<"读取数据失败"<<std::endl;break;// exit(1);}// std::cout << "我是子进程,我的rfd是" << rfd << std::endl;sleep(1);}}bool Create() // 初始化管道{for (int i = 0; i < _process_num; i++){// 创建匿名管道int pipefd[2] = {0};int n = pipe(pipefd);if (n < 0)return false; // 失败了// 创建子进程pid_t nid = fork();if (nid == 0) // 子进程负责读{//让子进程关闭自己继承下来的哥哥进程的写端关闭就可以了//只会影响引用计数不关闭父进程写端_cm.CloseAll();//写实拷贝所以不会影响父进程。子进程每次关闭都只关子进程的close(pipefd[1]); // 将写端关闭Work(pipefd[0]); // 读端工作close(pipefd[0]);exit(0); // 工作完就退出即可}else if (nid < 0) // 创建失败{std::cout << "子进程创建失败" << std::endl;return false;}else // 父进程{// char buf[1024];close(pipefd[0]); // 读端关闭_cm.InsterChannel(pipefd[1], nid); // 将这个子进程加入数组保存// close(pipefd[1]); // 写端关闭要在最后才关闭}}return true;}void Debug(){_cm.PrintfChannel();}void PushTask()//写任务{//不能选择一个子进程一直用啊//下面三种实现负载均衡方案//1. 轮询 2. 随机 3. Channel添加一个负载指标,通过是否达成指标来//1. 选一个任务int taskcode=_tm.Code();//随机选一个任务//2. 选择一个信道 子进程auto& c=_cm.Select();std::cout<<"选择了一个子进程"<<c.Name()<<std::endl;//3. 发送任务c.Send(taskcode);//传任务码std::cout<<"发送了一个任务码:"<<taskcode<<std::endl;}void Stop(){// //关闭父进程所有的wfd// _cm.StopSubprocess();// //回收所有子进程// _cm.WaitSubprocess();_cm.CloseAndWait();}~ProcessPool(){}private:ChannelManage _cm; // 管理所有的管道int _process_num; // 进程数量TaskManager _tm;//管理所有的任务
};
Task.hpp
#pragma once
#include <cstdio>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <vector>
#include <string>
#include <ctime>
typedef void (*task_t)();//函数指针void PrintfLog()
{std::cout<<"我是打印日志的任务"<<std::endl;
}void Download()
{std::cout<<"我是下载文件的任务"<<std::endl;
}void Upload()
{std::cout<<"我是上传文件的任务"<<std::endl;
}class TaskManager
{
public:TaskManager(){srand(time(nullptr));}void Register(task_t t)//注册{_tasks.push_back(t);}int Code(){return rand()%_tasks.size();}void Execute(int code){if(code>=0&&code< _tasks.size())//在数组范围内{_tasks[code]();//根据传递来的任务码来执行任务}}~TaskManager(){}
private:std::vector<task_t> _tasks;
};
main.cpp
#include"processpoll.hpp"int main()
{ProcessPool pp(5);pp.Create();// pp.Debug();int cnt=10;while(cnt--){//1. 选择一个信道pp.PushTask();sleep(1);}pp.Stop();// sleep(1000);return 0;
}
这篇就到这里啦(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤
相关文章:
Linux:进程间通信->匿名管道实现内存池
1. 进程间通信 (1) 概念 进程间通信(IPC) 就是不同进程间交换数据的方法,进程间是独立的所以不能访问彼此的内存,需要某种机制来通信(管道、消息队列,共享内存等) (2) 目的 数据传输:一个进程需要他的数据发送给另一个进程 资源…...
Linux服务器离线安装ollama及大模型
Linux服务器离线安装ollama及大模型 核心思路:使用一台可以联网的电脑将需要的ollama安装包和大模型下载到本地,之后传输到Linux服务器上安装并配置 环境说明 联网机:macOS M1Pro Linux服务器:x86_64 安装ollama版本:…...
C++ 类及函数原型详解
一、引言 在C 编程中,类(Class)是面向对象编程的核心概念之一,它是一种用户自定义的数据类型,封装了数据和操作数据的函数(成员函数)。函数原型则为函数的声明提供了必要的信息,让编…...
大内存生产环境tomcat-jvm配置实践
话不多讲,奉上代码,分享经验,交流提高! 64G物理内存,8核CPU生产环境tomcat-jvm配置如下: JAVA_OPTS-server -XX:MaxMetaspaceSize4G -XX:ReservedCodeCacheSize2G -XX:UseG1GC -Xms48G -Xmx48G -XX:MaxGCPauseMilli…...
各类前端开发的框架比较及其核心特性、开发体验、生态系统以及在不同项目中的适用性
前端开发框架多种多样,每种框架都有其独特的优势和局限性。以下是几种流行的前端框架及其特点、优缺点和适合的项目类型介绍:包括它们的核心特性、开发体验、生态系统以及在不同项目中的适用性。 1. React.js 核心特性: 虚拟DOM:…...
Git基本使用(很详细)
一:Git 概述 1.1 定义:分布式版本控制系统 1.2 版本控制 (1)定义: 版本控制时一种记录文件内容变化,以便将来查阅特定版本修订情况的系统 (2)举例 多副本 优化: 不使用多…...
mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析
以下是 com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析: 1. 类的作用 MybatisMapperProxy 是 MyBatis-Plus 框架中用于实现 Mapper 接口动态代理的核心类。它继承自 MyBatis 的 MapperProxy,并扩展了以下功能: …...
[密码学实战]商用密码产品密钥体系架构:从服务器密码机到动态口令系统
[密码学实战]商用密码产品密钥体系架构:从服务器密码机到动态口令系统 关键词:商用密码、密钥体系、服务器密码机、金融数据密码机、动态口令、智能密码钥匙 摘要:本文深度解读商用密码产品的核心密钥体系架构,涵盖服务器密码机、…...
BongoCat - 跨平台键盘猫动画工具
本文翻译整理自:https://github.com/ayangweb/BongoCat 文章目录 一、关于 BongoCat相关链接资源关键功能特性 二、下载安装系统要求下载方式macOSWindowsLinux (X11) 三、灵感来源四、效果演示 一、关于 BongoCat BongoCat 是一款跨平台的键盘猫动画工具…...
跨Linux发行版CPU指令集兼容性深度解析与实践指南
一、指令集差异全景透视 1.1 Ubuntu与Debian指令集差异对比 # 查询语句: lscpu | grep Flags # 结果 # Ubuntu 22.04 LTS Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma dcpop asimddp asimdfhm ssbs# De…...
docker的安装和简单使用(ubuntu环境)
环境准备 这里用的是linux的环境,如果没有云服务器的话,就是用虚拟环境吧。 虚拟环境的安装参考:vmware17的安装 linux镜像的安装 docker安装 我使用的是ubuntu,使用以下命令: 更新本地软件包索引 sudo apt u…...
Flutter 环境搭建 (Android)
目标 上一篇Flutter应用已经能在iOS,macOS和,chrome环境下正常运行了,这次把Android跑通。 环境 macOS 15.4.1 Visual Studio Code 1.99.3 Flutter 3.29.3 • channel stable • https://github.com/flutter/flutter.git Framework • revision ea121f8859 (11 da…...
数字化技术的五个环节:大数据、云计算、人工智能、区块链、移动互联网
在21世纪的科技浪潮中,数字化技术以其强大的生命力和无限的潜力,正逐步重塑着我们的世界。大数据、云计算、人工智能、区块链、移动互联网,这五大数字化技术的环节,如同构建智慧未来的基石,每一方面都承载着推动社会进…...
PWNOS:2.0(vulnhub靶机)
文章目录 靶机地址主机发现、端口扫描web渗透目录探测漏洞利用权限提升 解密工具地址总结 靶机地址 https://download.vulnhub.com/pwnos/pWnOS_v2.0.7z 这里如果是windows系统直接使用vmware或者virtubox打开可以使用,如果是mac系统需再去做一个配置,比较麻烦 这里…...
ubuntu22.04部署Snipe-IT
文章目录 参考链接一、写在前二、安装操作系统三、安装 PHP四、下载 Snipe-IT五、安装依赖六、安装数据库并创建用户七、安装 Snipe-IT八、安装 Nginx九、Web 继续安装 Snipe-IT补充: 最后 参考链接 How to Install Snipe-IT on Ubuntu 22.04 https://www.rosehost…...
【EDA】EDA中聚类(Clustering)和划分(Partitioning)
在VLSI物理设计自动化中,聚类(Clustering)和划分(Partitioning)是两个不同的关键步骤,主要区别如下: 1. 目标与核心任务 聚类(Clustering) 目标:将电路中的…...
Java 安全:如何实现用户认证与授权?
Java 安全:如何实现用户认证与授权? 在当今数字化的世界中,用户认证与授权是 Java 应用程序安全的关键环节。它们确保只有经过授权的用户才能访问特定资源,保护系统免受未授权访问的威胁。本文将深入探讨如何在 Java 中实现用户认…...
六个能够白嫖学习资料的网站
一、咖喱君的资源库 地址:https://flowus.cn/galijun/share/de0f6d2f-df17-4075-86ed-ebead0394a77 这是一个学习资料/学习网站分享平台,包含了英语、法语、德语、韩语、日语、泰语等几十种外国语言的学习资料及平台,这个网站的优势就是外语…...
AWS Glue ETL设计与调度最佳实践
一、引言 在AWS Glue中设计和调度ETL过程时,需结合其无服务器架构和托管服务特性,采用系统化方法和最佳实践,以提高效率、可靠性和可维护性。本文将从调度策略和设计方法两大维度详细论述,并辅以实际案例说明。 二、调度策略的最…...
《深入理解 AOP》
一、AOP 是什么 AOP(Aspect Oriented Programming),即面向切面编程,是软件开发中一种重要的编程范式。它通过横向抽取机制,将那些与业务逻辑本身无关、却为业务模块所共同调用的逻辑或责任(如事务处理、日…...
2022李宏毅老师机器学习课程笔记
机器学习笔记目录 1.绪论(内容概述)2.机器学习和深度学习的基本概念transformer 1.绪论(内容概述) 机器学习:让机器找一个函数,通过函数输出想要的结果。应用举例:语音识别,图像识别…...
时序数据库IoTDB在航空航天领域的解决方案
在快速发展的航空航天领域,高效、安全的数据管理成为了技术创新和持续发展的关键支撑。时序数据库IoTDB,凭借其国产自研、高效低流量数据同步、丰富的部署选择等优势,为航空航天产业提供了强有力的数据基础,助力产业加速转型升级。…...
洛谷 B3647:【模板】Floyd 算法
【题目来源】 https://www.luogu.com.cn/problem/B3647 【题目描述】 给出一张由 n 个点 m 条边组成的无向图。 求出所有点对 (i,j) 之间的最短路径。 【输入格式】 第一行为两个整数 n,m,分别代表点的个数和边的条数。 接下来 m 行,每行三…...
【25软考网工】第三章(4)生成树协议、广播风暴和MAC地址表震荡
目录 一、生成树协议1. 生成树技术背景1)单链路上行存在单点故障2)二层环路问题3)二层环路问题——广播风暴实验验证 广播风暴例题1:二层环路故障现象4)二层环路问题—— MAC地址表震荡实验验证 MAC地址表震荡的现象 2…...
解释器体系结构风格-笔记
解释器(Interpreter)是一种软件设计模式或体系结构风格,主要用于为语言(或表达式)定义其语法、语义,并通过解释器来解析和执行语言中的表达式。解释器体系结构风格广泛应用于编程语言、脚本语言、规则引擎、…...
删除新安装IBM Guardium Data Protection 12.1的baltimorecybertrustroot证书
登录web console,会显示 baltimorecybertrustroot证书过期警告。 采用下面的命令删除过期证书就可消除警告。 collector02.cpd.com> delete certificate keystore Select an alias from the list below to delete the corresponding certificate. Alias List:…...
反序列化漏洞1
一、PHP类与对象 1. 类 概念理解: 类是共享相同结构和行为的对象的集合,可以理解为特征的提取。例如将耳朵长、尾巴短、红眼睛、吃胡萝卜、蹦跳行走的动物特征抽象为"兔子"类。代码结构: 使用class关键字定义类类名遵循大驼峰命名法包含成员变量(属性)和…...
正则表达式三剑客之——awk命令
目录 一.什么是awk 二.awk的语法格式 1.选项 2. 模式(Pattern) 3. 操作(Action) 4. 输入文件(file) 5.总结 三.awk的工作原理 1. 逐行扫描输入 2. 匹配模式 1.正则表达式: 2.逻辑表…...
施磊老师基于muduo网络库的集群聊天服务器(七)
文章目录 数据表字符集问题支持中文和英文**为什么使用 utf8mb4?** 推荐 查看整个表, 再单独修改 客户端群组功能创建群组添加群组群组聊天接收在线群组消息接收离线群组消息补充服务器事件处理器补充服务器查询群组列表问题解决测试 目前报错总结目前为止最恶心的错…...
多模态(3):实战 GPT-4o 视频理解
最近,OpenAI 团队的 GPT-4o 模型,在多模态方面的能力有了大幅提升,这次我们就使用 GPT-4o 完成一个视频理解的实战。 1. 环境搭建 1.1 安装 FFmpeg 做视频处理,我们需要用到 FFmpeg 这款功能强大的开源多媒体处理工具。FFmpeg…...
基于python实现一个二维图片的路径规划问题
一、场景 基于如下的一个楼层平面图,假设有几个预置的点(实际项目中可能是动态的点,比如找车位,找工位),做路径规划,并画在平面图上 二、方案 1.准备平面室内图 可以自己用QGIS/cad等其他方式…...
云服务器centos 安装hadoop集群
百度 搜索 云服务器centos 安装hadoop 创建Hadoop用户 sudo useradd hadoop -m -s /bin/bash sudo passwd hadoop 123456 下载Hadoop wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.4/hadoop-3.2.4.tar.gz 解压并移动Hadoop到指定目录 tar …...
【k8s】sidecar边车容器
一、Sidecar 模式简介 Sidecar 模式是一种常见的微服务架构设计模式。它通过将附加功能或服务与主应用程序部署在同一容器或主机上,从而实现对主应用程序的增强和扩展。Sidecar 的名称来源于摩托车的边车,它与摩托车紧密相连,为主车提供额外…...
Web漏洞--XSS之订单系统和Shell箱子
本文主要内容 手法 XSS平台使用 XSS工具使用 XSS结合其他漏洞 XSS具体使用场景 某订单系统XSS盲打_平台 某Shell箱子系统XSS盲打_工具 [1]订单系统经典案例 第一个简易攻击流程(订单系统):通过平台完成XSS跨站之后&a…...
# 构建词汇表:自然语言处理中的关键步骤
构建词汇表:自然语言处理中的关键步骤 在自然语言处理(NLP)任务中,词汇表(Vocabulary)是文本数据预处理的核心组件之一。它将文本中的单词或字符映射为数值索引,从而让计算机能够理解和处理语言…...
新!在 podman-machine-default 中安装 CUDA、cuDNN、Anaconda、PyTorch 等并验证安装
#工作记录 一、前言 在 Windows 系统开发环境中,Podman Desktop 凭借强大的容器管理与 WSL-Linux 子系统集成能力备受开发者关注。 其中,podman-machine-default 是 Podman Desktop 安装后自带的默认 WSL-Fedora 子系统,支持与显卡通信&am…...
python_BeautifulSoup提取html中的信息
目录 描述: 过程: step one 下载html网页到本地 step two 提取html信息 list_con soup.select(.list-con) [0] li_list list_con.find_all(li) a li.find(span).find(a) title a.get(title) url a.get(href) span li.find(span).find(spa…...
pcd2pgm的launch文件实现
1.新建工作空间和克隆代码 mkdir -p pcd2pgm_launch/src && cd pcd2pgm_launch/src git clone https://github.com/Hinson-A/pcd2pgm_package 2. 编译 cd .. catkin_make -j4 3.修改launch 在launch文件目录下,可以用gedit 打开launch文件,…...
Vue里面elementUi-aside 和el-main不垂直排列
先说解决方法 main.js少导包 import element-ui/lib/theme-chalk/index.css; //加入此行即可 问题复现 排查了一个小时终于找出来问题了,建议导包去看官方的文档,作者就是因为看了别人的导包流程导致的问题 导包官网地址Element UI导包快速入门...
论文阅读:2024 ACL ArtPrompt: ASCII Art-based Jailbreak Attacks against Aligned LLMs
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Artprompt: Ascii art-based jailbreak attacks against aligned llms https://www.doubao.com/chat/3846685176618754 https://arxiv.org/pdf/2402.11753 https://github…...
项目maven版本不一致 导致无法下载
路程:打开一个新项目发现,maven加载不了 报错: Error running ‘dataManage [clean]’ No valid Maven installation found. Either set the home directory in the configuration dialog or set the M2_HOME environment variable on your s…...
论文阅读:2024 NeurIPS Group Robust Preference Optimization in Reward-free RLHF
Group Robust Preference Optimization in Reward-free RLHF https://www.doubao.com/chat/3870738843518978 https://arxiv.org/pdf/2405.20304 速览 研究动机 传统RLHF忽视群体偏好差异,导致模型对少数群体表现不佳,需提升群体鲁棒性。研究问题 如…...
数据可视化平台产品介绍及功能特色
数据可视化平台是一款适用于高校教学和各领域企业的零门槛可视化工具,能够解决高校数据分析与可视化类课程教学、实训问题。平台通过浏览器即可访问,无需安装客户端。平台内置公式编辑器与指标构建器,学生可通过四则运算、分组聚合等方式衍生…...
MySQL索引优化、SQL分析与运行原理 - Java架构师面试实战
MySQL索引优化、SQL分析与运行原理 - Java架构师面试实战 第一轮提问 面试官:马架构,请问您对MySQL的B树索引有什么理解? 马架构:B树是一种平衡多路查找树,所有的数据节点都存储在叶子节点上。相比于B树,…...
C++学习:六个月从基础到就业——STL:函数对象与适配器
C学习:六个月从基础到就业——STL:函数对象与适配器 本文是我C学习之旅系列的第二十九篇技术文章,也是第二阶段"C进阶特性"的第八篇,主要介绍C STL中的函数对象与适配器。查看完整系列目录了解更多内容。 引言 在前面的…...
Linux基础篇、第四章_02磁盘及分区管理fdisk 和 gdisk
题目:Linux 磁盘及分区管理 版本号: 1.0,0 作者: 老王要学习 日期: 2025.04.25 适用环境: Centos7 文档说明 本教程适用于 Centos7 环境,详细介绍 Linux 磁盘及分区管理操作。包含虚拟机添加磁盘的关机与开机添加方法、MBR 和 GPT 两种分区方式特点、…...
火山云的市场竞争
火山云是字节跳动旗下的云计算服务,对吧?那它的竞争对手应该包括国内外的大型云服务提供商。首先,国际市场上,像AWS、Azure、Google Cloud这些巨头肯定是大头。国内的话,阿里云、腾讯云、华为云这些应该都是主要的竞争…...
创建型设计模式之:简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式
创建型设计模式之:简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式 (一)简单工厂模式 简单工厂模式将对象的实例化过程封装到一个工厂类中,根据输入的条件创建不同类型的对象。 角色划分: 抽象产品…...
【Linux内核设计与实现】第三章——进程管理01
文章目录 1. 引言2. 进程&线程——概念3. 进程控制块/进程描述符(PCB)4. 进程内核栈(Kernel Stack)4.1. 进程内核栈的定义4.2. thread_info 体系结构相关进程描述4.3. 定位进程描述符(task_struct)和内核栈以及内核栈指针的问题 5. 进程 IDÿ…...
正大模型视角下的市场结构判断逻辑
正大模型视角下的市场结构判断逻辑 在多数交易策略中,结构识别往往先于方向判断。以正大的数据研判风格为例,其核心逻辑是:价格行为不能孤立解读,必须结合时间与成交效率来判断当前结构的有效性。 例如,一个上涨过程&…...