linux共享内存共享消息队列

linux共享内存共享消息队列

初衷

​ 又想使用共享内存的高效,又想使用队列来让两个进程进行异步通信。

用到的系统调用

1. ftok

​ 每个共享内存都要有一个对应的key相关联

#include <sys/ipc.h>
key_t ftok(const char *path, int id);

//path为要共享的路径
//id为0-255之间的整数,自己取
//成功返回key,失败返回-1

2. shmget

创建共享段并返回一个共享段的标识符

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t, size_t size, int shmflg);

//Key 为ftok生成的key
//size为共享内存的大小
//shmflg标志代表所需要的操作和权限
//	IPC_CREAT 创建一个新的段,如果没用这个flg,他就会找和key关联的段,并检查你有没有对应权限
//  IPC_EXCL  该flg和IPC_CREAT一起使用以确保创建了段,如果对应的段已经存在了,则会调用失败
//  
//  返回共享内存段的标识符,失败返回-1

//基本会使用上面两个,剩余可去问男人(man)

3. shmat

获取共享段地址

#include<sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

//shmid为shmget返回的id
//shaddr为制定共享内存出现在进程内存地址的什么位置,如果为NULL,系统将选择一个合适(未使用的)的页面地址来将共享内存段和进程内存对齐,如果不为NULL,并且在shmflg设置了SHM_RND,他会将共享内存段和SHMLBA对齐(SHMLBA问男人)
//shmflg为对数据的操作,如果指定SHM_RDONLY则以制度方式连接共享段,其他值为rw方式连接该内存段。
//返回值:成功返回指向共享存储段的指针;错误返回-1

4. shmdt

当不需要对共享段操作的时候,可以用它来分离(不是删除共享段

#include<sys/shm.h>

int shmdt(const void *shmaddr);

//shmaddr为shmat返回的地址指针
//成功返回0,错误-1

5. shmctl

对共享段进行控制,比如删除它

#include<sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

//shmid为shmget返回的标识符
//cmd代表你要做的操作,
//  删除是IPC_RMID
//  IPC_STAT 得到共享段的状态
//  IPC_SET 改变共享段的状态 将buf所指的一些成员数据写入内核为共享内存维护的一个buf里

//成功返回0,失败-1

demo

通过共享内存在两个进程中使用同一个struct,可以在struct封装链表/队列等,这里懒就没写

还有原谅我有的地方不加错误判断和在C++里面写C

//wirte.cpp 进行写操作

#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <cstdio>

struct data {
    int pos;
    char name[8];
};

int main() {
    key_t key = ftok("./", 123);
    int id = shmget(key, 1024*5, IPC_CREAT|0666);
    if(id == -1) {
        std::cout << "faild" << std::endl;
        exit(-1);
    }
    else std::cout << "shmget success" << std::endl;
    
    data *pmap;
    pmap = (data *)shmat(id, 0, 0);
    pmap->pos = 888;
    strncpy(pmap->name, "liar", 4);
    
    std::cout << "write success" << std::endl;
    sleep(10);
    shmdt(pmap);
    shmctl(id, IPC_RMID, 0);
    return 0;
}
//read.cpp 进行读操作; 

#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <cstdio>

struct data {
    int pos;
    char name[8];
};

int main() {
    key_t key = ftok("./", 123);
    int id = shmget(key, 1024*5, 0);

    data *pmap;
    pmap = (data *)shmat(id, 0, 0);
    std::cout << "name is :" << pmap->name << std::endl;
    std::cout << "pos is :" << pmap->pos << std::endl;
    shmdt(pmap);
    return 0;
}

查看IPC

ipcs -m #查看ipc
ipcrm -m id #删除ipc
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值