Linux shmget/shmat/shmctl共享内存
来源:互联网 发布:淘宝怎么加入聚划算 编辑:程序博客网 时间:2024/05/22 03:26
标识符和键
每个内核中的IPC结构都用一个非负整数的标识符加以引用。无论何时创建IPC结构,都应指定一个键。这个键的数据类型是基本系统数据类型key_t,通常在头文件< sys/types.h >中被定义为长整型。这个键由内核变换成标识符。
ftok创建键
#include <sys/ipc.h>key_t ftok(const char* path, int id);
path参数必须引用一个现有的文件。当产生键时,只使用id参数的低8位。
ftok函数的实现:
通过path取得其stat结构的st_dev
通过path取得其stat结构的st_ino
id的低序8位
在访问同一共享内存的多个进程先后调用ftok函数的时间段中,如果 path指定的文件被删除且重新创建,则文件系统会赋予这个同名文件新的inode节点信息,于是这些进程所调用的ftok虽然都能 正常返回,但得到的键值却并不能保证相同。
shmget函数
shget函数创建一个新的共享内存区,或者访问一个已存在的共享内存区。
#include <sys/shm.h>int shmget(key_t key, size_t size, int oflag);
返回值是一个称为共享内存区标识符的整数,其他三个shmXXX函数就用它来代指这个内存区。
key既可以是ftok的返回值,也可以是IPC_PRIVATE(创建一个新的IPC结构)
size以字节为单位指定内存区的大小,若是创建一个新的共享内存区则size不能为0,否则相反
oflag是读写权限值的组合,同open函数的0777权限值一般
shmat函数
连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问
#include <sys/shm.h>void *shmat(int shmid, const void* shaddr, int flag);
shmid为shmget函数成功返回的标识符
shaddr,指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
flag读写权限值的组合
关于shaddr参数:
如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND值
如果没有指定SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址
如果指定SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址向下舍入一个SHMLBA常值。
shmctl函数
shmctl提供了对一个共享内存区的多钟操作
#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buff);
shmid共享内存标识符
cmd提供了三个命令
- IPC_RMID 从系统中删除由shmid标识的共享内存区并拆除它
- IPC_SET 给指定的共享内存区设置其shmid_ds结构的以下三个成员: shm_perm.uid、shm_perm.gid和shm_perm.mode,它们的值来自buff参数指向的结构中的相应成员。shm_ctime的值也用当前时间替换
- IPC_STAT 通过buff参数向调用者返回指定共享内存区当前的shmid_ds结构
共享内存管理结构体。
炒鸡简单示例
#include<stdio.h>#include<sys/shm.h>#include<unistd.h> #include<string.h>#include<stdlib.h> #define SHM_SIZE 1024 int main() { // 创建共享内存对象 int shmid = shmget(IPC_PRIVATE, SHM_SIZE, 0777); // 获取共享内存指针 char* shmptr; shmptr= shmat(shmid, 0, 0); strcpy(shmptr,"hello shm"); printf("%s",shmptr); // free shmctl(shmid, IPC_RMID, 0); return 0; }
非血缘进程共享映射区通信
server
#include<stdio.h>#include<sys/ipc.h>#include<unistd.h>#include<sys/shm.h>#include<string.h>int main(){ // 通过文件创建key key_t mykey = ftok("test.txt",0x03); if(mykey < 0) { printf("ftok err\n"); return -1; } // 获得标识符 int shmid = shmget(mykey,4096,IPC_CREAT|IPC_EXCL|0600); if(shmid < 0) { printf("shmget err\n"); return -1; } // 获得指向共享内存的指针 char* shmptr = (char*)shmat(shmid, NULL, 0); if(shmptr == NULL) { printf("shmat err\n"); return -1; } // 写入 const char* tmp = "hello salute"; strcpy(shmptr,tmp); shmptr[strlen(tmp)] = '\0'; printf("wait\n"); getchar(); // 清空并断开 shmctl(shmid,IPC_RMID,0); return 0;}
client
#include<stdio.h>#include<sys/ipc.h>#include<unistd.h>#include<sys/shm.h>#include<string.h>int main(){ // 通过文件创建key key_t mykey = ftok("test.txt",0x03); if(mykey < 0) { printf("ftok err\n"); return -1; } // 获得标识符 int shmid = shmget(mykey,4096,0600); if(shmid < 0) { printf("shmget err\n"); return -1; } // 获得指向共享内存的指针 char* shmptr = (char*)shmat(shmid, NULL, 0); if(shmptr == NULL) { printf("shmat err\n"); return -1; } printf("%s",shmptr); return 0;}
- Linux shmget/shmat/shmctl共享内存
- linux 共享内存(shmget,shmat,shmdt,shmctl)解析
- linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)
- linux ----进程共享内存通信(shmget,shmat,shmdt,shmctl)
- linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)
- 共享内存函数(shmget、shmat、shmdt、shmctl)
- 共享内存 shmget()、shmat()、shmdt()、shmctl()
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- IPC--共享内存 Share Memory 实例(shmget shmat shmdt shmctl)
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)及其范例
- 共享内存函数(shmget、shmat、shmdt、shmctl)
- 操作Checkbox标签
- 统计一个整数里面出现次数最多最大的数字
- 在大学里我们应该学习什么
- 用T-SQL语句创建数据库
- L1-005. 考试座位号
- Linux shmget/shmat/shmctl共享内存
- 结构型之装饰模式
- 微信公众号用java中控服务器-实现用户网页授权和获取使用JS-SDK权限
- 19-marquee跑马灯标签
- 伙伴算法
- 关于乱码的解决方案
- c++ emplace操作
- 第一个Java程序Test.java开发、编译、解释和总结
- 20-b,u,i,s,这些被删除的标签以及用来替换他们的标签