C++ 创建共享内存
共享内存用于实现进程间大量的数据传输,共享内存是在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问时间等。返回值:(1)成功,返回共享内存标识符(2)出错,返回-1,错误原因存于errno中。shmflag: 指定共享内存的访问权限和映射条件,一般设置为0,即读写权限。返回值:成功:0,出错:-1,错误原因存在于errno中。返回值:成功:0,出错:-1,
共享内存用于实现进程间大量的数据传输,共享内存是在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问时间等。
1、shmget函数
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
作用:得到或者创建共享内存
参数:
key: 创建共享内存的标识符,最好用16进制表示。
size: 创建共享内存段的字节数大小。
flag: 共享内存段的创建标识
IPC_CREAT //如果不存在就创建
IPC_EXCL //如果存在则返回失败
IPC_NOWAIT //如不等待直接返回
返回值:(1)成功,返回共享内存标识符(2)出错,返回-1,错误原因存于errno中。
2、shmat函数
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
作用: 将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址
参数:
shmid:共享内存空间标识符,即ID。
shmaddr:指定共享内存的映射地址。如果为0(NULL),则由系统选择映射的地址,推荐设置为0。如果非0,并且没有指定SHM_RND,则该值即为映射共享内存的地址。
shmflag: 指定共享内存的访问权限和映射条件,一般设置为0,即读写权限。
/* Flags for `shmat'. */
#define SHM_RDONLY 010000 /* attach read-only else read-write */
#define SHM_RND 020000 /* round attach address to SHMLBA */
#define SHM_REMAP 040000 /* take-over region on attach */
#define SHM_EXEC 0100000 /* execution access */
3、shmdt函数
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
作用:shmdt是shmat的反操作,用于将共享内存和当前进程分离。在共享内存使用完毕后都要调用该函数。
参数:shmaddr:指定共享内存的映射地址。
返回值:成功:0,出错:-1,错误原因存在于errno中。
4、shmctl函数
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
作用:共享内存的内存管理
参数:shmid:共享内存空间标识符,即ID。
cmd:
- 公共的IPC选项(ipc.h中):
IPC_RMID //删除
IPC_SET //设置ipc_perm参数
IPC_STAT //获取ipc_perm参数
IPC_INFO //如ipcs
- 共享内存自己的选项(shm.h中)【需要root权限】
SHM_LOCK //锁定共享内存段
SHM_UNLOCK //解锁共享内存段
buf:共享内存管理结构体。具体说明参见共享内存内核结构定义部分,一般设置为0.
返回值:成功:0,出错:-1,错误原因存在于errno中。
共享内存的代码如下:
#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <thread>
#define SHARE_MEM_SIZE 2048
int main()
{
int shmid = 0; //内存标识符
//创建共享内存
shmid = shmget((key_t)0x5005,SHARE_MEM_SIZE,0640|IPC_CREAT);
if(-1 == shmid)
{
std::cout << "create shareMem failed." << std::endl;
return -1;
}
char* pMemSharedMem = 0;
//将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址
pMemSharedMem = (char*)shmat(shmid,0,0);
std::cout << "read context: " << pMemSharedMem << std::endl;
std::string strContext = "hello world, "+ std::to_string(getpid());
strncpy(pMemSharedMem,strContext.c_str(),strContext.length());
std::cout << "write after: " << pMemSharedMem << std::endl;
//shmat的反操作,将共享内存与当前进程分离
shmdt(pMemSharedMem);
#if 0
//操作共享内存, IPC_RMID //删除共享内存,在不使用共享内存的时候进行调用
if(shmctl(shmid,IPC_RMID,0) == -1)
{
std::cout << "delete shared Mem fialed." << std::endl;
return -1;
}
#endif
return 0;
}
第一次运行结果如下:
第二次运行结果如下:
上面的例子存在进程间的同步问题,可以结合信号量的用法来同步进程间的数据操作。
5、查看创建共享内存命令:ipcs -m
删除共享内存的命令:ipcrm -m shm_id
具体例子可参考共享内存查看删除等_٩(•̮̮̃•̃)۶的博客-CSDN博客
附加:
共享内存的创建函数也可参考:
更多推荐
所有评论(0)