IPC
机制无需内核介入。所有需要做的就是让一个进程将数据复制进共享内存中,并且这部分数据会对其他所有共享同一个段的进程可用。IPC
技术的速度更快。shmget()
创建一个新共享内存段或取得一个既有共享内存段的标识符(即由其他进程创建的共享内存段)。这个调用将返回后续调用中需要用到的共享内存标识符。shmat()
来附上共享内存段,即使该段成为调用进程的虚拟内存的一部分。shmat()
调用返回的 addr
值,它是一个指向进程的虚拟地址空间中该共享内存段的起点的指针。shmdt()
来分离共享内存段。在这个调用之后,进程就无法再引用这块共享内存了。这一步是可选的,并且在进程终止时会自动完成这一步。需要这一块的共享内存连接数为0时才会删除,所以叫标记删除!
shmctl()
来删除共享内存段。只有当当前所有附加内存段的进程都与之分离之后内存段才会销毁。只有一个进程需要执行这一步int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
key_t ftok(const char *pathname, int proj_id)
ipcs
用法 ipcs -a
// 打印当前系统中所有的进程间通信方式的信息
ipcs -m
// 打印出使用共享内存进行进程间通信的信息ipcs -q
// 打印出使用消息队列进行进程间通信的信息ipcs -s
// 打印出使用信号进行进程间通信的信息ipcrm
用法
ipcrm -M shmkey
// 移除用shmkey
创建的共享内存段ipcrm -m shmid
// 移除用shmid
标识的共享内存段ipcrm -Q msgkey
// 移除用msqkey
创建的消息队列ipcrm -q msqid
// 移除用msqid
标识的消息队列ipcrm -S semkey
// 移除用semkey
创建的信号ipcrm -s semid
// 移除用semid
标识的信号int shmget(key_t key, size_t size, int shmflg);
- 功能:创建一个新的共享内存段,或者获取一个既有的共享内存段的标识。
新创建的内存段中的数据都会被初始化为0
- 参数:
- key : key_t类型是一个整形,通过这个找到或者创建一个共享内存。
一般使用16进制表示,非0值
- size: 共享内存的大小
- shmflg: 属性
- 访问权限
- 附加属性:创建/判断共享内存是不是存在
- 创建:IPC_CREAT
- 判断共享内存是否存在: IPC_EXCL , 需要和IPC_CREAT一起使用
IPC_CREAT | IPC_EXCL | 0664
- 返回值:
失败:-1 并设置错误号
成功:>0 返回共享内存的引用的ID,后面操作共享内存都是通过这个值。
void *shmat(int shmid, const void *shmaddr, int shmflg);
- 功能:和当前的进程进行关联
- 参数:
- shmid : 共享内存的标识(ID),由shmget返回值获取
- shmaddr: 申请的共享内存的起始地址,指定NULL,内核指定
- shmflg : 对共享内存的操作
- 读 : SHM_RDONLY, 必须要有读权限
- 读写: 0
- 返回值:
成功:返回共享内存的首(起始)地址。 失败(void *) -1
int shmdt(const void *shmaddr);
- 功能:解除当前进程和共享内存的关联
- 参数:
shmaddr:共享内存的首地址
- 返回值:成功 0, 失败 -1
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- 功能:对共享内存进行操作。删除共享内存,共享内存要删除才会消失,创建共享内存的进行被销毁了对共享内存是没有任何影响。
- 参数:
- shmid: 共享内存的ID
- cmd : 要做的操作
- IPC_STAT : 获取共享内存的当前的状态
- IPC_SET : 设置共享内存的状态
- IPC_RMID: 标记共享内存被销毁
- buf:需要设置或者获取的共享内存的属性信息
- IPC_STAT : buf存储数据
- IPC_SET : buf中需要初始化数据,设置到内核中
- IPC_RMID : 没有用,NULL
key_t ftok(const char *pathname, int proj_id);
- 功能:根据指定的路径名,和int值,生成一个共享内存的key
- 参数:
- pathname:指定一个存在的路径
/home/nowcoder/Linux/a.txt
/
- proj_id: int类型的值,但是这系统调用只会使用其中的1个字节
范围 : 0-255 一般指定一个字符 'a'
#include
#include
#include
#include
#include
int main()
{
// 系统获取key值
key_t key = ftok("/home/nowcoder/Linux/lesson27/", 2);
printf("write_shm key: %d\n", key);
// 创建共享内存,返回值为shmid,为共享内存的唯一标识
int shmid = shmget(key, 1024, IPC_CREAT | 0664);
printf("write_shm shmid: %d\n", shmid);
// 关联内存,设置权限为读写
void* address = shmat(shmid, NULL, 0);
char* str = "hello world";
memcpy(address, str, strlen(str) + 1);
printf("按任意键继续\n");
getchar();
// 取消当前进程和共享内存的关联
shmdt(address);
// 删除共享内存
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
#include
#include
#include
#include
#include
int main()
{
// 系统获取key值
key_t key = ftok("/home/nowcoder/Linux/lesson27/", 2);
printf("read_shm key: %d\n", key);
// 创建共享内存,返回值为shmid,为共享内存的唯一标识
int shmid = shmget(key, 1024, IPC_CREAT);
printf("read_shm shmid: %d\n", shmid);
// 关联内存,设置权限为读写
void* address = shmat(shmid, NULL, 0);
printf("%s\n", (char*) address);
printf("按任意键继续\n");
getchar();
// 取消当前进程和共享内存的关联
shmdt(address);
// 删除共享内存
shmctl(shmid, IPC_RMID, NULL);
return 0;
}