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

福田祥菱十大seo免费软件

福田祥菱,十大seo免费软件,海口免费自助建站模板,山东淄博疫情最新消息封城📖 前言:本期介绍共享内存。 目录 🕒 1. 共享内存的原理🕒 2. 共享内存的概念🕘 2.1 接口认识🕘 2.2 演示生成key的唯一性🕘 2.3 再谈key 🕒 3. 共享内存相关命令🕒 4. 利…

📖 前言:本期介绍共享内存。


目录

  • 🕒 1. 共享内存的原理
  • 🕒 2. 共享内存的概念
    • 🕘 2.1 接口认识
    • 🕘 2.2 演示生成key的唯一性
    • 🕘 2.3 再谈key
  • 🕒 3. 共享内存相关命令
  • 🕒 4. 利用共享内存进行进程间通信
  • 🕒 5. 共享内存的优缺点

🕒 1. 共享内存的原理

在之前学过的进程地址空间的基础上,我们知道,进程之间具有独立性,因为每个进程的内核数据结构的数据以及页表的映射都是独立的。而对于共享内存,我们同样了解,这是为了让进程之间能够进行通信的公共空间,接下来就通过进程地址空间的结构去了解共享空间的位置及原理:
在这里插入图片描述

OS为了让两个毫不相关的进程之间进行通信,进行了三个工作:

  1. 在对应的内存当中让用户帮OS申请一块空间(通过指定的调用接口)
  2. 将创建好的内存映射进进程的地址空间(用户就可以通过访问起始地址的方式来进行对申请的这块内存空间的访问)
  3. 未来不想通信:
    • 取消进程和内存的映射关系
    • 释放内存

因此,我们把申请的这块空间称之为共享内存,将映射关系称之为进程和共享内存进行挂接。将取消进程和内存的映射关系称之为去关联,释放内存释放的就是共享内存。

理解

  • 进程间通信,是专门设计的,用来IPC的,和malloc/new不是一个东西。
  • 共享内存是一种通信方式,所有想通信的进程,都可以用。
  • OS中一定会存在着很多共享内存。

🕒 2. 共享内存的概念

通过让不同的进程,看到同一个内存块的方式,叫做共享内存。

🕘 2.1 接口认识

#include<sys/ipc.h>
#include<sys/shm.h>int shmget(key_t key, size_t size, int shmflg);// size:共享内存的大小

对于shmflg,常见的有两种选择:

  • IPC_CREAT:如果不存在共享文件则创建,存在则获取
  • IPC_EXCL
    • 无法单独使用,单独使用没有意义,需要结合IPC_CREAT
    • IPC_CREAT|IPC_EXCL:如果不存在,就创建,如果已存在,就出错返回。即在用户的角度,如果创建成功,一定是一个新的shm

shmget返回值: 记住他是一个标识符就够用了,得到的是共享内存的标识符。(和文件fd没有任何关系)

key: 是什么不重要,最重要的是其具备的唯一性。

而获取key值,则通过一个新的接口:ftokftok通过指定的字符串数据*pathname以及char类型的proj_id数据进行一系列的算法整合返回了具有唯一性的Key:

key_t ftok(char *pathname, char proj_id);

由于创建的key值有可能已经被别人使用了,因此有失败的可能性。创建Key值如果失败,则返回-1。

🕘 2.2 演示生成key的唯一性

# Makefile
.PHONY:all
all:shm_client shm_servershm_client:shm_client.ccg++ -o $@ $^ -std=c++11
shm_server:shm_server.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f shm_client shm_server
// comm.hpp
#ifndef _COMM_HPP_
#define _COMM_HPP_#include<iostream>
#include<cerrno>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<sys/ipc.h>
#include<sys/shm.h>#define PATHNAME "."//当前路径
#define PROJ_ID 0x66key_t getKey()
{key_t k = ftok(PATHNAME, PROJ_ID);if(k < 0){// cin, cout, cerr ->stdin, stdout, stderr->0, 1, 2;标准错误stderr向2打印。std::cerr << errno << ":" << strerror(errno) << std::endl;exit(1);//终止进程}return k;
}#endif
// shm_server.cc
#include"comm.hpp"int main()
{key_t k = getKey();printf("0x%x\n", k);return 0;
}
// shm_client.cc
#include"comm.hpp"int main()
{key_t k = getKey();printf("0x%x\n", k);return 0;
}
[hins@VM-12-13-centos shm]$ ./shm_server
0x6601062a
[hins@VM-12-13-centos shm]$ ./shm_client
0x6601062a

通过make后执行发现,两个程序的k值是一样的,这就证明了ftok指定参数的返回值是唯一的。(k实际上就是32位的一个整数)

🕘 2.3 再谈key

OS中一定存在多个共享内存,因为彼此之间可能都需要通信,因此也就都需要申请一块空间。而OS申请的共享空间,也一定和进程一样需要被管理,既然需要管理,那么一定也是先描述再组织的方式,即共享内存 = 物理内存块+共享内存的相关属性 。

之前谈到过,key是什么不重要,能进行唯一性的标识最重要,因此创建共享内存的时候,是如何保证共享内存在系统中是唯一的呢?当然是通过key来确定的,只要一个进程也看到了同一个key,就能够访问这个共享内存。那么key在哪里,实际上这就和PCB一样,key就在内核中的属性集合里,即:

struct shm{key_t key;//...
}

即:key是通过shmget这样的系统调用,设置进入共享内存属性中,用来表示该共享内存在内核中的唯一性!

shmid和key就好比fd和inode。为什么有了key还需要shmid呢?通过key和shmid的区分,能够面向系统层面和用户层面,这样能够更好的进行解耦,以免内核中的变化影响到用户级。

🕒 3. 共享内存相关命令

通过让不同的进程,看到同一个内存块的方式,叫做共享内存。

查看共享内存ipcs -m/-q/-s (共享内存/消息队列/信号量数组)

删除共享内存ipcrm -m shmnid

将共享内存与虚拟内存进行关联:

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);// 共享内存id,被映射的进程地址空间(给nullptr),给0默认可以读写。成功时,将返回共享内存的虚拟地址。失败返回-1(失败错误码errno被设置) 

将共享内存与虚拟内存去关联

#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);//参数:shmat的返回值。成功时,将返回0。失败返回-1(失败错误码errno被设置)

控制(主要用移除)共享内存(shmctl)

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);//shmid(类似fd),传入系统设定的宏,shmid_ds数据结构。传入IPC_RMID移除共享内存成功时,将返回0。失败返回-1(失败错误码errno被设置)

🕒 4. 利用共享内存进行进程间通信

// comm.hpp
#pragma once
#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define PATHNAME "."//当前路径(路径都行)
#define PROJ_ID 0X55//项目id也无要求
#define MAX_SIZE 4096
key_t getKey()
{key_t k=ftok(PATHNAME, PROJ_ID);if(k==-1){std::cout<<"ftok"<<errno<<":"<<strerror(errno)<<std::endl;exit(1);}return k;
}
int getShmHelper(key_t key,int flags)
{int shmid=shmget(key,MAX_SIZE,flags);if(shmid==-1)//创建共享内存失败{std::cerr<<"shmget"<<errno<<":"<<strerror(errno)<<std::endl;exit(2);}return shmid;//返回共享内存标识符
}
int getShm(key_t key)//创建||获取共享内存
{return getShmHelper(key,IPC_CREAT);//传0也行
}
int createShm(key_t key)//必定创建共享内存
{return getShmHelper(key,IPC_CREAT|IPC_EXCL|0600);//生成一个全新的共享内存
}
void* attachShm(int shmid)//让共享内存与虚拟内存建立联系
{void* memstart=shmat(shmid,nullptr,0);if((long long)memstart==-1L){std::cerr<<"shmat"<<errno<<":"<<strerror<<std::endl;exit(3);}return memstart;
} 
void detchShm(void* memStart)//去关联
{if(shmdt(memStart)==-1){std::cerr<<"shmdt"<<errno<<":"<<strerror<<std::endl;exit(4);}
}   
void delShm(int shmid)//删除共享内存
{if(shmctl(shmid,IPC_RMID,nullptr)==-1){std::cerr<<"shmctl"<<errno<<":"<<strerror<<std::endl;}
}
// shm_server.cc
#include "comm.hpp"
int main()
{key_t k=getKey();printf("0X%x\n",k);int shmid=createShm(k);char* memStart=(char*)attachShm(shmid);//让共享内存与虚拟内存建立联系printf("memStart address:%p\n",memStart); //通信接收代码while(true){printf("client say:%s\n",memStart); sleep(1);//调用用户级结构体struct shmid_ds ds;//创建结构体对象dsshmctl(shmid,IPC_STAT,&ds);//获取ds对象的状态printf("获取属性:%d,pid:%d,myself:%d,key:%d\n",ds.shm_segsz,getpid(),ds.shm_cpid,ds.shm_perm.__key);}detchShm(memStart);//去关联sleep(10);delShm(shmid);//删除共享内存,client和server都能删除共享内存,尽量谁创建谁删return 0;
}
// shm_client.cc
#include "comm.hpp"
int main()
{key_t k=getKey();printf("0X%x\n",k);int shmid=getShm(k);//获取共享内存sleep(5);char* memStart=(char*)attachShm(shmid);//让共享内存与虚拟内存建立联系printf("memStart address:%p\n",memStart); //通信传输代码const char* massage="I am client";pid_t id=getpid();int cnt=0;//发送计数while(true){snprintf(memStart,MAX_SIZE,"%s[%d]:%d\n",massage,getpid,++cnt);sleep(1);}detchShm(memStart);//去关联return 0;
}

🕒 5. 共享内存的优缺点

优点:共享内存是所有进程间通信中速度最快的。(无需缓冲区,能大大减少通信数据的拷贝次数)

缺点:如果服务端读取速度较快,用户端发送数据较慢,就会产生同一段消息被服务端读取多遍。共享内存是不进行同步和互斥的,没有对数据进行任何保护。

共享内存大小的建议:因为系统分配共享内存是以4KB为基本单位,一般建议申请共享内存的大小为4KB的整数倍。


OK,以上就是本期知识点“共享内存”的知识啦~~ ,感谢友友们的阅读。后续还会继续更新,欢迎持续关注哟📌~
💫如果有错误❌,欢迎批评指正呀👀~让我们一起相互进步🚀
🎉如果觉得收获满满,可以点点赞👍支持一下哟~

❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页

http://www.dt0577.cn/news/57527.html

相关文章:

  • 河北网站推广优化深圳网络推广
  • 做网站费用会计分录怎么做专业seo网络推广
  • 网站策划方案目标重庆排名优化整站优化
  • 建一个个人网站一年多少钱北京cms建站模板
  • 青岛的网站建设徐州seo排名公司
  • 贵司不断优化网站建设网推拉新app推广平台
  • 潍坊建设网站公司电话吴中seo页面优化推广
  • 啥前端框架可以做网站首页太原seo计费管理
  • 做燕鲍翅的网站网络推广外包怎么样
  • 天津网站优化公司哪家专业雅虎搜索引擎首页
  • 黔南网站建设十堰seo排名公司
  • 成人本科要读几年济宁seo公司
  • 河北正规网站建设比较产品软文撰写
  • 电商网站设计与制作青岛网站制作公司
  • 网站b站最好看的纪录片软件女生做sem专员的工作难吗
  • 临沂网站建设求职简历免费下载百度seo
  • 百度建立企业网站建设的目的精准粉丝引流推广
  • 专业网站开发多少钱百度竞价防软件点击软件
  • icp对网站内容百度提交收录入口
  • 东莞公司品牌网站建设网址ip地址查询工具
  • 在企业网站建设的解决方案中如何写好软文推广
  • 网站建设域名什么意思seo主要优化哪些
  • 装修房子的效果图 三室二厅二卫产品seo标题是什么
  • 今日疫情实时大数据潍坊seo推广
  • 怎么做付费网站优化大师app
  • 东莞网站建设推广咨询平台重庆seo服务
  • WordPress建站要花钱外包网络推广公司怎么选
  • 手机网站模板 php我想学做互联网怎么入手
  • 扬州市市政建设处网站新媒体运营培训班
  • 手机小程序开发教程深圳将进一步优化防控措施