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

网站模板漏洞企业seo关键词优化

网站模板漏洞,企业seo关键词优化,推广平台开户代理,做营销型网站费用文章目录● 是什么 ?● 共享内存的原理● 使用到的系统调用● 总结● 共享内存的使用完整代码一 、效果展示二 、共享内存的优缺点(重点)● 与管道通信方式对比● 思维导图总结● 是什么 ? System V 共享内存是进程间通信(IPC)中性能最高的机制…

文章目录

  • 是什么 ?
  • 共享内存的原理
  • 使用到的系统调用
    • 总结
  • 共享内存的使用完整代码
  • 一 、效果展示
  • 二 、共享内存的优缺点(重点)
  • 与管道通信方式对比
  • 思维导图总结


是什么 ?


  System V 共享内存是进程间通信(IPC)中性能最高的机制,其核心思想是让多个进程直接访问同一块物理内存区域,避免数据在进程地址空间之间的拷贝。 共享内存通过内存映射实现进程间数据的直接读写,适用于需要频繁交换大量数据的场景(如数据库缓存、高性能计算数据共享)。


共享内存的原理


  上面提到了共享内存是通过映射的 , 下面具体看看怎么映射 .

在这里插入图片描述


那如果两个进程呢 ?? 共享内存又是什么呢 ??

  现在 , 在内存中申请了一块空间 , 那么要通信 , 怎么做 ?

在这里插入图片描述

  所以 , 这也是为什么叫共享内存的原因了 , 两个不同的进程间共享同一块内存进行通信 , 那操作系统会不会有很多进程都要通信呢 ?? 肯定要 , 所以 , 就会存在多个共享内存 , 那么这么多共享内存 , 操作系统要不要被管理呢 ??? 答 : 要 . 怎么管理 ??? 答 : 先描述 , 再组织 ! 那就意味着 , 在操作系统中一定是有管理共享内存的数据结构对象的 , 并不是简单的映射 !

  • 再次理解 , 那么映射需要映射全部地址块吗 ??

在这里插入图片描述


使用到的系统调用


  那么 , 问题来了 ?? 以上的原理映射是谁在做 ?? 答 : 操作系统 , 那么我们能直接访问操作系统吗 ?? 做不到 , 所以 , 我们需要用系统调用来让操作系统帮我们完成 !

  所以 , 需要根据以下步骤创建 , 使用 , 销毁 .

  • 创建共享内存

shmget 系统调用 (key 用 ftok系统调用构建)

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

使用代码练习

#include <iostream>
// 创建共享内存的头文件
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>int main()
{// 创建共享内存// shmget(key_t key , size_t size , int shmflg)// 构建 Key//注意 :  "." . 是一个硬链接 , 指向一个文件 , 所以本质是文件路径 key_t key = ftok("." , 0x112233);//返回值 : 成功返回 key , 否则返回 -1 并设置错误码if(key > 0)std::cout << "ftok success , ftok = " << key << std::endl; int shmid = shmget(key , 1024 , IPC_CREAT);//返回值 :  成功返回合法的标识符 , 失败返回 -1 并设置错误码// 这个返回值是给我们用户用的 , 我们访问共享内存都用这个标识符if(shmid > 0){std::cout << "shmget success , shmget = " << shmid << std::endl; }return 0;
}
  • 查看共享内存命令

ipcs -m 可以查看创建的共享内存 !

在这里插入图片描述

  • 映射共享内存 , 即 : 挂接共享内存

      共享内存创建好了 , 就要映射到进程地址空间中了 . 即 : 将共享内存和进程关联(挂接) !

shmat 系统调用 , 可以通过查看共享内存中的相关信息 – nattch 查看关联数

在这里插入图片描述

  auto shm_addrr = shmat(shmid , nullptr , 0);
  • 去关联 , 即 : 去掉页表映射关系(删除共享内存前)

shmdt 系统调用

在这里插入图片描述

  • 共享内存的删除 , 即 : 命令删除时用这个

ipcrm -m shmid

  注意 : 删除时只能用 shmid 删除 , 即 : 唯一标识符 !

  • 共享内存的控制 , 即 : 代码删除时用这个

shmctl 系统调用
在这里插入图片描述


总结

在这里插入图片描述


共享内存的使用完整代码

分为这样几个文件 : 客户端 : client.cc , 服务端 : server.cc , 共享内存的实现 : shm.hpp , 共同代码 : common.hpp , Makefile

共享内存的实现 : shm.hpp

// 这个文件是实现共享内存
// 因为共享内存被创建出来是映射到进程地址空间的 , 所以用户只需要拿到进程地址空间中被映射的起始虚拟地址
// 和共享内存的大小就能全部访问了
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include "common.hpp"// 共享内存
class Shm_m
{//这里面的所有函数不暴露给外面使用 , 只有自己使用 
private:// 公共函数 , 共享内存帮助函数// 因为创建和获取只有选项不同 , 其余相同 !void Shm_mHelper(int shmflg){// 在创建之前先要生成 key// shmget(key_t key , size_t size, int shmflg);_shmid = shmget(_key, SHM_MNUM, shmflg);if (_shmid > 0)std::cout << "shmget shmid [ " << _shmid << " ] success ! " << std::endl;elseERR_EXIT("shmget");}void Create(){std::cout << CREATER << " creating ..." << std::endl;Shm_mHelper(IPC_CREAT | IPC_EXCL | gmode);}// 获取共享内存 -- client 来完成void GetShm_m(){std::cout << USER << " geting ..." << std::endl;Shm_mHelper(IPC_CREAT);}// 删除前想要去挂接 , 即 : 去掉映射关系void DeleteAttach(){// int shmdt(const void *shmaddr);//  传入挂接后的起始虚拟地址int n = shmdt(_shm_addrr);if (n == 0){std::cout << "shmdt shmid [ " << _shmid << " ] success !" << std::endl;}else{std::cout << "shmdt shmid [ " << _shmid << " ] fail ..." << std::endl;}}// 销毁共享内存void Destory(){// int shmctl(int shmid, int cmd, struct shmid_ds *buf);int n = shmctl(_shmid, IPC_RMID, nullptr); // 目前不用带回内核数据结构中的信息 !if (n != -1){std::cout << "shmctl rm [ " << _shmid << " ] success !" << std::endl;}else{std::cout << "shmctl rm [ " << _shmid << " ] fail .... " << std::endl;}}public:Shm_m(const std::string &usertype): _shm_addrr(nullptr), _size(SHM_MNUM), _shmid(-1), _key(-1), _usertype(usertype){// 创建 key_key = ftok(PATH, PRO_ID);if (_key < 0){ERR_EXIT("ftok");}// 只让服务端进行创建 , 也就是 CREATERif (usertype == CREATER){// 创建共享内存Create();}if (usertype == USER){// 获取共享内存GetShm_m();}}~Shm_m(){// 只让创建者删除共享内存if (_usertype == CREATER){// 去挂接DeleteAttach();Destory();}}// 创建共享内存 -- server 来完成// 两个进程都是要进行挂接的//  进行挂接 (映射到进程的虚拟的地址空间中)void Attach(){// void *shmat(int shmid, const void *shmaddr, int shmflg);//  返回的是挂接的虚拟地址空间位置的虚拟起始地址_shm_addrr = shmat(_shmid, nullptr, 0);int id = getpid();if (_shm_addrr != (void *)-1){std::cout << "shmat [ " << _shmid << " ] to pid [ " << id << " ] success !" << std::endl;}else{ERR_EXIT("shmat");}}// 虚拟地址void *VirtualAddar(){return _shm_addrr;}private:void *_shm_addrr;      // 起始虚拟地址size_t _size;          // 共享内存的大小key_t _key;            // 给内核用的唯一标识符keyint _shmid;            // 给我们用的共享内存标识符std::string _usertype; // 使用类型 , 即 : 目前谁使用
};

共同代码 : common.hpp

// 这个是共同文件 , 两个进程共同需要的代码放到这里//创建 key 需要路径和我们给定的一个值 , 二者结合才是 key
// "." 这个是硬链接 , 本质还是一个文件路径
#define PATH "."
#define PRO_ID 0x112233
#include <cstdio>
#include <cstdlib>// 要创建的共享内存多大 
#define SHM_MNUM  4096//权限
const int gmode = 0666; 
//定义两个身份
#define CREATER "Server"
#define USER "Client"//打印错误信息
#define ERR_EXIT(m) \
do { \perror(m); \exit(EXIT_FAILURE); \
}while(0)

服务端 : server.cc

// 这个文件是服务端 
// 服务端负责 :
// 1 . 创建共享内存
// 2 . 接收共享内存传来的客户端发来的消息
// 3 . 结束后 , 销毁共享内存 , 必须用代码或指令删除 , 因为共享内存生命周期随内核 !#include "shm.hpp"int main()
{Shm_m shm(CREATER); // 构造时会自动创建共享内存 // 2.  挂接 , 映射到进程地址空间 shm.Attach();//挂接完成后 , 即 : 映射到两个进程虚拟地址空间中了 , 至此二者看到了同一份资源//然后就可以通信了 !//所以 , 服务端就可以使用共享内存来通信了 , 怎么使用 ?? 得到的就是一块内存 , 有地址直接用即可 !// 3. 获取映射后的虚拟起始地址char* addar = (char*)shm.VirtualAddar();// 4. 进行通信 , 读取共享内存中的内容 int cnt = 0;while(true){//直接读printf("I am %s , %s say : %s\n" , CREATER , USER , addar);std::string st = addar;if(st.rfind('Z') == 25){std::cout << USER << " exit , me too !" << std::endl;break;}sleep(1);}   //服务端还要负责销毁共享内存 , 因为共享内存生命周期随内核 , 不用了需要销毁 !// 5 . 销毁 //这里进程结束 , 会走析构函数 , 析构时会自动进行销毁 return 0;
}

客户端 : client.cc

// 这个文件是客户端
// 客户端和服务端的通信采用共享内存的方式
// 客户端负责 :
// 给服务端发送消息 , 目的让客户端接收到消息// 所以 , 对客户端来说 , 只需要获取共享内存的起始虚拟地址和大小就可以拿到整个共享内存了#include "shm.hpp"int main()
{Shm_m shm(USER); // 构造时会自动获取共享内存 // 挂接shm.Attach();// 挂接完成后 , 即 : 映射到两个进程虚拟地址空间中了 , 至此二者看到了同一份资源//获取虚拟地址char* addar = (char*)shm.VirtualAddar();//获取后当做一个字符数组 , 客户端只负责写内容 !for(int i = 'A'; i <= 'Z'; ++i){addar[i-'A'] = i;sleep(1);}//告诉另一个进程我要退了 !std::cout << "I exit !" << std::endl;return 0;
}

Makefile

.PHONY:all  # 这一行必写 , 因为默认执行第一行 , 否则无法直接生成两个可执行程序
all:server client
server:server.ccg++ -o $@ $^ -std=c++11
client:client.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f server client 

一 、效果展示

在这里插入图片描述

  可以看到 , 二者可以完成通信 , 但不知道有没有发现一个细节 , 以下笔者会讲 !


二 、共享内存的优缺点(重点)


  这里再看一个图 :

在这里插入图片描述

  这里可以看到一个现象 , 就是当 server 端创建好共享内存与client 进行通信时 , 一旦启动 server 端 , 那么 server 端会读共享内存中的内容 , 但是特点是 : 其不会等待其它进程 , 会直接从共享内存中读取内容 !

  也就是说 , 共享内存通信的机制就是不用等待通信方发来消息我在读 , 而是只要有了共享内存启动了直接读(即使内容为空) !

这就与管道的通信机制不同了 , 因为管道是文件 , 用到 read 读取 , 所以管道通信时需要等通信方发来消息才会读 , 否则就一直阻塞等待了 !

  • 那共享内存这样的机制有没有什么缺点呢 ??

   肯定是有的 . 想想 , 共享内存不会等待通信方 , 所以就会导致读到的内容不一致 , 本来通信方想要发 : AABB , 想让读的一方这样读 , 但是因为共享内存的特殊性 , 只要有内容就读 , 所以会导致 : 通信的双方的数据不一致问题 , 这就是没有同步机制 , 这样的数据就不会被保护了 , 所以 , 共享内存没有保护机制 !

  • 总结

在这里插入图片描述


  那么 , 想要解决这种缺点有没有方法 ?? 答 : 有的 , 需要用到锁 !


与管道通信方式对比

在这里插入图片描述


思维导图总结

在这里插入图片描述

http://www.dtcms.com/wzjs/434176.html

相关文章:

  • wordpress 调用短代码广州网站设计实力乐云seo
  • dw做链接网站无法显示该页面网上永久视频会员是真的吗
  • 税务网站建设 目标seo快速优化报价
  • 天元建设集团有限公司商业承兑汇票信誉怎么样专业搜索引擎seo服务商
  • wordpress仿站价格2021年网络热点舆论
  • 建筑网站建设案例百度网盘网站入口
  • 十大暴利行业加盟aso优化前景
  • 如何建设好党建网站爱战网关键词挖掘
  • 创建网站建设营销网点机构号
  • 网站开发fsdpjq西安优化外包
  • 上海网站制作软件东莞seo网络公司
  • 20亿做网站热搜排行榜今日排名
  • 宏宇网站建设谷歌seo 优化
  • 西安做网站服务微信营销的方法7种
  • 贵阳汽车网站建设中国突然宣布一重磅消息
  • 营销型网站建设公司电话seo推广收费标准
  • 专卖店vi设计公司seo优化教程自学网
  • 上行10m企业光纤做网站vue seo优化
  • 做英文网站需要多少旺道营销软件
  • 比较好看的网站设计北京推广
  • 整站seo哪家服务好微信小程序开发平台
  • wordpress做网站优点哈尔滨百度推广公司
  • 华西医院网站开发武汉网络推广外包公司
  • 让别人做网站要注意什么6企业qq怎么申请
  • 沈阳网站建设的价格自助建站系统源码
  • 村委会网站源码 php企业网站搭建
  • 长春建设工程信息网站东莞做网页建站公司
  • 施工企业负责人每月带班时间不少于seo零基础教学
  • 绍兴网站设计泉州关键词搜索排名
  • 网络营销服务有哪些企业站seo报价