当前位置: 首页> 科技> 名企 > 中国免费企业建站_恶搞图片在线制作_品牌宣传策略有哪些_seo投放是什么意思

中国免费企业建站_恶搞图片在线制作_品牌宣传策略有哪些_seo投放是什么意思

时间:2025/8/6 5:11:41来源:https://blog.csdn.net/2302_78684687/article/details/145386606 浏览次数:1次
中国免费企业建站_恶搞图片在线制作_品牌宣传策略有哪些_seo投放是什么意思

--------------------------------------------------------------------------------------------------------------------------------

每日鸡汤:一旦相爱下去,就应共有一株向日葵。不管谁是太阳,都要时时辐射温暖;不管谁是向日葵,都要不渝地仰望。

-------------------------------------------------------------------------------------------------------------------------------- 

目录

一:直接原理

1.1、申请共享内存

1.2、释放共享内存

二:直接代码展示

2.1、创建共享内存—shmget

2.2、共享内存挂载—shmat

2.3、共享内存去挂载(关联)—shmdt

2.4、控制共享内存—shmctl

2.5、通信代码

三:共享内存的特性

四:扩展内容代码

4.1 获取共享内存中的属性

4.2 使用管道对共享内存实现同步机制

五:结语


一:直接原理

进程间通信的本质是:先让不同的进程,看到同一份资源。

1.1、申请共享内存

三步申请法:

  1. 操作系统在内存上去申请一段空间
  2. 将申请到的内存挂接到进程地址空间的共享区
  3. 返回起始虚拟地址

1.2、释放共享内存

释放共享内存:去关联,释放内存。

这些一系列操作(申请、挂载、去关联、释放)并不是进程自己做的,而是由操作系统完成的。即我们用户(进程)通过调用一些系统调用接口让操作系统来做这些事情。因为OS中肯定有很多进程都在相互交互、通信的,那么操作系统内肯定存在多个共享内存。所以操作系统就要把这些共享内存管理起来(先描述,再组织)。故在操作系统内核中肯定有结构体来描述共享内存。

二:直接代码展示

2.1、创建共享内存—shmget

       #include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);
  • 参数 key:决定保证让不同的进程看到同一个共享内存;让我们知道这个共享内存是否存在。
  • 参数 size:要创建的共享内存的大小,单位是字节。
  • 参数 shmflg:一个标记位。选项 IPC_CREAT:创建一个共享内存,若不存在直接创建,存在直接获取并返回,一般单独使用;选项 IPC_EXCL:若申请的共享内存存在,错误返回,一般不单独使用。选项 IPC_CREAT | IPC_EXCL:创建共享内存,若不存在则创建,存在,出错返回,确保我们申请成功的共享内存一定是一个新的。
  • 返回值:创建共享内存成功,返回共享内存标识符;失败返回-1 

再谈参数 key:

  • key是一个数字,数字是几不重要,关键在于它必须在内核中具有唯一性,能够让不同进程进行唯一性标识。
  • 第一个进程可以通过key创建共享内存,第二个之后的进程,只要拿着同一个key就可以和第一个进程看到同一个共享内存了。
  • 对于一个已经创建好的共享内存,key哎共享内存中的描述对象中。
  • 第一个创建共享内存的时候,必须已经有一个 key 了。
  • “key 就类似于路径,一定要具有唯一性”

使用 ftok 函数调用来创建一个 key

 key VS shmid(共享内存标识符)

  • key:在操作系统内标定唯一性
  • shmid:只在你的进程内,用来表示资源的唯一性

查看共享内存:ipcs -m

共享内存的生命周期是随内核的,只要用户不主动关闭,共享内存会一直存在,除非内核重启或者用户关闭释放。

删除共享内存:ipcrm -m shmid

共享内存的大小,一般建议是 4096 的整数倍,而假设申请 4097 字节的共享内存,实际上操作系统给你的是 4096*2的大小,就会造成资源的浪费。

2.2、共享内存挂载—shmat

       #include <sys/types.h>#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);
  • 参数 shmid:申请共享内存返回的共享内存标识符
  • 参数 shmaddr:由OS决定,一般设为 nullptr
  • 参数 shmflg:一般设为0即可
  • 返回值:返回共享内存挂接在地址空间上虚拟的起始地址
// comm.hpp
#pragma once#include <iostream>
#include <string>
#include <cstring>#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#include "log.hpp"Log lg;
const std::string pathname = "/home/alin";
const int proj_id = 0x8888;
const int size = 4096;// 获取key值
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){lg(Fatal, "ftok error: %d, strerror: %s", errno, strerror(errno));exit(1);}lg(Info, "ftok success, key is : 0x%x", key);return key;
}// 由flag 来标记怎样申请共享内存
int GetShareMemHelper(int flag)
{key_t k = GetKey();int shmid = shmget(k, size, flag);if(shmid < 0){lg(Fatal, "create share memory error: %d, strerror", errno, strerror(errno));exit(2);}lg(Info, "create share memory success, shmid is : %d", shmid);return shmid;
}// 创建共享内存
int CreateShm()
{return GetShareMemHelper(IPC_CREAT | IPC_EXCL | 0666);
}// 获取共享内存
int GetShm()
{return GetShareMemHelper(IPC_CREAT);
}
// prcessa.cc
#include "comm.hpp"int main()
{// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);return 0;
}

2.3、共享内存去挂载(关联)—shmdt

  • 参数 shmaddr:挂接时获取的起始虚拟地址 
  • 返回值:成功返回0,失败返回-1
#include "comm.hpp"int main()
{// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);// ipc code// 共享内存去挂载shmdt(shmaddr);return 0;
}

2.4、控制共享内存—shmctl

  • 参数 cmd:决定做什么操作。IPC_STAT:将内核中共享内存中的属性拷贝到 buff 中;IPC_RMID:删除共享内存,将该共享内存标记为0。
  • 参数 struct shmid_ds:一个共享内存的结构体,内部保存了共享内存的属性
// processa.cc
#include "comm.hpp"int main()
{// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);// ipc code// 共享内存去挂载shmdt(shmaddr);// 释放共享内存shmctl(shmid, IPC_RMID, nullptr);return 0;
}

2.5、通信代码

// processa.cc
#include "comm.hpp"int main()
{// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);// ipc codewhile (true){std::cout << "client say# " << shmaddr << std::endl;sleep(1);}// 共享内存去挂载shmdt(shmaddr);// 释放共享内存shmctl(shmid, IPC_RMID, nullptr);return 0;
}
// processb.cc
#include "comm.hpp"int main()
{// 获取共享内存int shmid = GetShm();// 挂载char* shmaddr = (char*)shmat(shmid, nullptr, 0);// ipc codewhile(true){std::cout << "Please Enter@ ";fgets(shmaddr, 4094, stdin);}shmdt(shmaddr);return 0;
}

一旦有了共享内存,并且已经挂接到自己的地址空间中了,直接把它当成你的内存空间来使用即可,不需要调用用系统调用接口了,一旦有人把数据写到共享内存,其实我们立马就能看见了,不需要经过系统调用直接就能看到数据了。

三:共享内存的特性

  • 共享内存没有同步互斥之类的保护机制
  • 共享内存是所有的进程间通信中,速度最快的。(数据拷贝次数少)
  • 共享内存中内部的数据,由用户自己维护

四:扩展内容代码

4.1 获取共享内存中的属性

通过 shmctl 函数来获取共享内存中属性。

#include "comm.hpp"int main()
{// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);// ipc codestruct shmid_ds shmds;while (true){std::cout << "client say# " << shmaddr << std::endl;sleep(1);shmctl(shmid,IPC_STAT, &shmds); // shmds输出型参数std::cout << "shm nattch: " << shmds.shm_nattch << std::endl;std::cout << "shm size: " << shmds.shm_segsz << std::endl;std::cout << "shm mode: " << shmds.shm_perm.mode << std::endl;printf("shm key: 0x%x\n", shmds.shm_perm.__key);sleep(5);}// 共享内存去挂载shmdt(shmaddr);// 释放共享内存shmctl(shmid, IPC_RMID, nullptr);return 0;
}

4.2 使用管道对共享内存实现同步机制

// comm.hpp
#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#include <sys/types.h>
#include <sys/stat.h>#include "log.hpp"Log lg;
const std::string pathname = "/home/alin";
const int proj_id = 0x6666;
// const int proj_id = 1024 ^ getpid();
const int size = 4096;// 获取key值
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){lg(Fatal, "ftok error: %d, strerror: %s", errno, strerror(errno));exit(1);}lg(Info, "ftok success, key is : 0x%x", key);return key;
}// 由flag 来标记怎样申请共享内存
int GetShareMemHelper(int flag)
{key_t k = GetKey();int shmid = shmget(k, size, flag);if (shmid < 0){lg(Fatal, "create share memory error: %d, strerror: %s", errno, strerror(errno));exit(2);}lg(Info, "create share memory success, shmid is : %d", shmid);return shmid;
}// 创建共享内存
int CreateShm()
{return GetShareMemHelper(IPC_CREAT | IPC_EXCL | 0666);
}// 获取共享内存
int GetShm()
{return GetShareMemHelper(IPC_CREAT);
}// 使用有名管道来实现同步机制
#define FIFO_FILE "./myfifo"
#define MODE 0666enum
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR
};class Init
{
public:Init(){// 创建管道int n = mkfifo(FIFO_FILE, MODE);if (n < -1){perror("mkfifo");exit(FIFO_CREATE_ERR);}}~Init(){int m = unlink(FIFO_FILE);if (m < -1){perror("unlink");exit(FIFO_DELETE_ERR);}}
};
// processa.cc
#include "comm.hpp"int main()
{Init init;// 创建共享内存int shmid = CreateShm();// 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);int fd = open(FIFO_FILE, O_RDONLY);if(fd < 0){lg(Fatal, "err code: %d, error string: %s", errno, strerror(errno));exit(FIFO_OPEN_ERR);}// ipc codestruct shmid_ds shmds;while (true){char c;ssize_t s = read(fd, &c, 1);if(s <= 0) break;std::cout << "client say# " << shmaddr << std::endl;// sleep(1);// shmctl(shmid,IPC_STAT, &shmds); // shmds输出型参数// std::cout << "shm nattch: " << shmds.shm_nattch << std::endl;// std::cout << "shm size: " << shmds.shm_segsz << std::endl;// std::cout << "shm mode: " << shmds.shm_perm.mode << std::endl;// printf("shm key: 0x%x\n", shmds.shm_perm.__key);// sleep(5);}// 共享内存去挂载shmdt(shmaddr);// 释放共享内存shmctl(shmid, IPC_RMID, nullptr);return 0;
}

// processb.cc
#include "comm.hpp"int main()
{// 获取共享内存int shmid = GetShm();// 挂载char* shmaddr = (char*)shmat(shmid, nullptr, 0);int fd = open(FIFO_FILE, O_WRONLY);if(fd < 00){lg(Fatal, "err code: %d, error string: %s", errno, strerror(errno));exit(FIFO_OPEN_ERR);}// ipc codewhile(true){std::cout << "Please Enter@ ";fgets(shmaddr, 4094, stdin);write(fd, "c", 1);}shmdt(shmaddr);return 0;
}

原理:没有管道时,a进程会一直读取共享内存中的数据,有了管道后,a进程在读取共享内存中的数据之前,会先从管道中读取,这个数据是随便的,只是为了读到特定信号,读取信号之后才可从共享内存中读取,否则一直阻塞在管道那里。当b进程向共享内存写入数据,写入数据之后,会给管道发送一个写入信号,而a进程阻塞在管道那里就是为了等待这一信号,当等待成功该信号中,a进程会立即读取共享内存中的数据,此时b进程已经向共享内存中写入了。这样就能实现共享内存中的同步与互斥。

五:结语

今天的分享到这里就结束了,如果觉得文章还可以的话,就一键三连支持一下欧。各位的支持就是捣蛋鬼前进的动力。

关键字:中国免费企业建站_恶搞图片在线制作_品牌宣传策略有哪些_seo投放是什么意思

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: