又想使用共享内存的高效,又想使用队列来让两个进程进行异步通信。
用到的系统调用 1. ftok 每个共享内存都要有一个对应的key相关联
#include2. shmgetkey_t ftok(const char *path, int id); //path为要共享的路径 //id为0-255之间的整数,自己取 //成功返回key,失败返回-1
创建共享段并返回一个共享段的标识符
#include3. shmat#include 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)
获取共享段地址
#include4. shmdtvoid *shmat(int shmid, const void *shmaddr, int shmflg); //shmid为shmget返回的id //shaddr为制定共享内存出现在进程内存地址的什么位置,如果为NULL,系统将选择一个合适(未使用的)的页面地址来将共享内存段和进程内存对齐,如果不为NULL,并且在shmflg设置了SHM_RND,他会将共享内存段和SHMLBA对齐(SHMLBA问男人) //shmflg为对数据的操作,如果指定SHM_RDONLY则以制度方式连接共享段,其他值为rw方式连接该内存段。 //返回值:成功返回指向共享存储段的指针;错误返回-1
当不需要对共享段操作的时候,可以用它来分离(不是删除共享段
#include5. shmctlint shmdt(const void *shmaddr); //shmaddr为shmat返回的地址指针 //成功返回0,错误-1
对共享段进行控制,比如删除它
#includedemoint shmctl(int shmid, int cmd, struct shmid_ds *buf); //shmid为shmget返回的标识符 //cmd代表你要做的操作, // 删除是IPC_RMID // IPC_STAT 得到共享段的状态 // IPC_SET 改变共享段的状态 将buf所指的一些成员数据写入内核为共享内存维护的一个buf里 //成功返回0,失败-1
通过共享内存在两个进程中使用同一个struct,可以在struct封装链表/队列等,这里懒就没写
还有原谅我有的地方不加错误判断和在C++里面写C
//wirte.cpp 进行写操作 #include#include #include #include #include #include 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查看IPC#include #include #include #include #include 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; }
ipcs -m #查看ipc ipcs -m id #删除ipc



