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

全球网站流量查询建设银行甘肃分行网站

全球网站流量查询,建设银行甘肃分行网站,新网互联的网站,网站建设 目标目录 前置: 一 原理 二 API 1. shmgetr 2. shmctl 3. 指令操作 2. 删除 3. 挂接 4. 断开挂接 三 demo代码 四 共享内存的特征 前置: 1.前面说的不管是匿名管道还是命名管道都是基于文件的思想构建的一套进程间通信的方案,那有没有…

目录

前置:

一 原理

二 API

1. shmgetr

2. shmctl

3. 指令操作

2. 删除

3. 挂接

4. 断开挂接

三 demo代码

四 共享内存的特征


前置:

1.前面说的不管是匿名管道还是命名管道都是基于文件的思想构建的一套进程间通信的方案,那有没有完全从0单独设计一套呢?

2. 共享内存作为 system v 标准,是由操作系统自主从0搭建的一套进程间通信机制,相对于管道而言也更快,那么下面来看看具体是怎么实现的。

一 原理

1. 进程之间通信之前必须要看到同一份资源,比如管道,看到同一个管道文件(路径),子进程继承父进程文件描述符。

2. 共享内存其实是在内存中开辟一段空间,并把起始地址映射到虚拟地址空间的共享区当中,访问这个虚拟地址也就访问到内存上的空间了,那么2个毫不相干的进程怎么看到这个共享内存呢?

3. 之前说的动态库,在程序运行期间在内存中寻找库文件,找不到在去磁盘上加载,所以在内存中有很多的动态库,势必也要管理维护起来并且提供一个字段来标识这个实例,共享内存也同样如此,在内存中也有个结构进行维护并标识起来。

4. 让不同进程看到同一份标识,系统提供了一个API

#include <sys/types.h>
#include <sys/ipc.h>key_t ftok(const char *pathname,  // 随便传入路径int proj_id            // 随便传入一个id// key_t -> int);

1. 传入一个路径和id并通过算法形成一个key_t结构,本质是int类型,算法是固定的,所以不同的进程传入相同的字符串和id得到的key_t都是一样的,这是用户传入数据生成的。

2. 返回值为-1错误,其他均正确。

所以不同的进程传入相同的路径和id就能看到同一个共享内存了。

5. 建立共享内存的映射,然后就需要进行把进程和共享内存进行挂接,也就是绑在一起,进行后续通信,结束在断开挂接。

6. 共享内存只有创建和挂接/断开挂接/释放共享内存的时候使用了系统调用,通信的时候不需要,所以直接在用户层直接向物理内存写入数据,是进程间通信里最快的,仅需一次拷贝物理内存里的数据。

二 API

1. shmgetr
#include <sys/ipc.h>
#include <sys/shm.h>int shmget(key_t key,    // 用户生成的 key 值 size_t size,  // 共享内存的大小int shmflg    // 选项: 创建/获取....);// 返回值: 内核维护的 shmid 值,用来管理共享内存的结构
2. shmctl
#include <sys/ipc.h>
#include <sys/shm.h>int shmctl(int shmid,            // shmget的返回值int cmd,              // 对共享内存: 删除/修改等操作struct shmid_ds *buf  // 共享内存的结构里的字段);
// 返回值: 成功为0,失败-1

为什么有了 key ,还要有 shmid ?key是用户形成的只是用来获取和创建共享内存的,并不能对已经存在的共享内存进行字段修改/结构修改等,只有shmid能操作,本质就是 shmid 属于内核提供的,key是有用户提供的,他们的功能侧重点不同,用户管用户,内核管内核,变相的解耦。 

3. 指令操作

1. 查看

ipcs -m // 共享内存相关信息
ipcs -q // 消息队列相关信息
ipcs -s // 信号量相关信息

查询到的字段

key:    用户形成的随机值,用来获取,创建访问共享内存。

shmid:shmget的返回值,用来管理共享内存结构的。

owner:谁创建的。

perms:权限是什么。

bytes: 共享内存多大。

nattch:谁挂接上了。

status: 状态标识。

2. 删除
ipcrm -m/q/s shmid
3. 挂接
#include <sys/types.h>
#include <sys/shm.h>void *shmat(int shmid,            // shmget的返回值const void *shmaddr,  // 共享内存的起始地址int shmflg            // 权限设置);
4. 断开挂接
#include <sys/types.h>
#include <sys/shm.h>int shmdt(const void *shmaddr // shmat的返回值);

三 demo代码

#include <iostream>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <cstring>// htok 用来形成随机的 key_t
const static std::string pathkey = "/home/CD/linux/shared_memory";
const static int projid = 123456;// 区分创建者和使用者
const static std::string Create = "Create";
const static std::string User = "User";// 共享内存大小
const int shmbuff = 4096;// 转16进制
std::string to_hex(int val)
{char buff[1024] = {0};snprintf(buff, 1024, "0x%x", val);return buff;
}// SHM类
class SHM
{
private:// 进行挂接bool Shmat(){_buff = shmat(_shmid, nullptr, 0);if (_buff == (void *)-1)return false;return true;}// 创建共享内存并获取 shmidbool Createshmid(){_shmid = shmget(_key, shmbuff, IPC_CREAT | IPC_EXCL | 0666);if (_shmid == -1){std::cout << "shmgid create failed" << std::endl;return false;}return true;}// 获取已经存在的共享内存的shmidbool Getshmid(){_shmid = shmget(_key, shmbuff, IPC_CREAT);if (_shmid == -1){std::cout << "shmget get failed" << std::endl;return false;}std::cout << _shmid << std::endl;return true;}public:// 构造对象SHM(const std::string &path, int proj_id, const std::string &who): _path(path), _proj_id(proj_id), _who(who), _buff(nullptr){_key = ftok(_path.c_str(), proj_id);if (_key == -1){std::cout << "ftok failed" << std::endl;exit(-1);}}// 创建共享内存/获取共享内存shmid/挂接共享内存/获取共享内存的起始地址void *run(){if (_who == Create){if (Createshmid() == false)exit(-2);if (Shmat() == false){std::cout << "Shmat failed" << std::endl;exit(-3);}}else{if (Getshmid() == false)exit(-2);if (Shmat() == false){std::cout << "Shmat failed" << std::endl;exit(-3);}}memset(_buff, 0, shmbuff);return _buff;}// 释放共享内存/断开挂起~SHM(){if (_who == Create){int n = shmctl(_shmid, IPC_RMID, nullptr);if (n == -1){std::cout << "ftok failed" << std::endl;exit(-3);}}if (_buff != nullptr)shmdt(_buff);}private:std::string _path;int _proj_id;std::string _who;int _shmid;key_t _key;void *_buff;
};

四 共享内存的特征

1. 由于通信是在用户层直接写到物理内存,没有系统调用,所以不像管道有read/write接口,read的时候没有数据内核会阻塞,而共享内存则没有任何保护机制,也就是无同步无互斥,所以需要应用层进行处理。

2. 共享内存是进程间通信里最快的,用户层直接通过共享映射的虚拟地址写入即可,无任何系统调用。

3. 共享内存的大小是 4k 为基本单位的,不符合倍数就向上取整。

4. 共享内存的生命周期随内核,除非手动代码/指令进行释放。

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

相关文章:

  • 网站基础三要素wordpress不发送邮件
  • 如何通过阿里云自己做网站网店怎么开店详细教程
  • 办一个购物网站要多少钱电商网站建设如何
  • 郑州哪有做网站的汉狮快速收录网站
  • 秦皇岛网站推广同一域名可以做相同网站吗
  • 小米商城网站开发文档网站建设早会说什么
  • 有哪些好的响应式网站wordpress菜单栏改成小写
  • 广州技术支持 奇亿网站建设网站的建设与维护步骤
  • 网站内容设计地方网站运营方案
  • 免费模版网站四川城乡建设部网站
  • 手机网站建设免费哈尔滨网站建设 哈尔滨网站推广
  • 小说网站开发的看书软件最好的网页设计公司
  • 建设门户网站需要多少钱外贸的推广平台
  • 专业做公司宣传网站的网络空间治理
  • 南通网站建设方案海尔电子商务网站建设预算
  • asp漂亮的个人网站模板湘潭做网站 z磐石网络
  • 静态网站是什么意思各种软件链接网址
  • 大连建站模板制作wordpress版权图片
  • 自建网站管理个人网站备案名字不同
  • 松滋市住房和城乡建设局网站asp官网
  • 青海企业网站开发定制网站首页制作方案
  • 网站美工设计收费单网页网站内容
  • 顺义区专业网站制作网站建设长沙雨花区建设局网站
  • 莱州网站建设多少钱wordpress管理工具栏
  • 网站空间管理面板专业网站定制设计公司
  • 宿州网站建设公司注册装修公司要多少钱才能注册
  • 让iis做跳转网站diy平台
  • 企业网站设计建设长春用c 建网站时怎么做导航菜单栏
  • mooc 网站建设情况建筑工程网络教育网
  • 用asp做网站优势wordpress浏览最多的文章