linuxC多进程通讯systemv---共享内存

相关API

•获取共享内存对象的ID: 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);
•查看IPC对象信息:$ ipcs -m

shmget

函数原型: int shmget(key_t key, size_t size, int shmflg);
•函数功能:创建或打开一个共享内存对象
•所需头文件:sys/types.h sys/shm.h
•函数参数
–Key:IPC对象的键值,一般为IPC_PRIVATE或ftok返回的key值
–Size:共享内存大小,一般为内存物理页的整数倍
–shmflg:
»IPC_CREAT:如果不存在与指定的key对应的段,那么就创建一个新段
»IPC_EXCL:若key指定的内存存在且指定了IPC_CREAT,返回EEXIST错误
»SHM_HUGETLB:使用巨页(huge page)
•返回值:共享内存的标识符ID

shmat

•函数原型: void *shmat (int shmid, const void *shmaddr, int shmflg);
•函数功能:将shmid标识的共享内存引入到当前进程的虚拟地址空间
•所需头文件:sys/shm.h
•函数参数
–shmid :共享内存的IPC对象 ID
–shmaddr
»若为NULL:共享内存会被attach到一个合适的虚拟地址空间,建议使用NULL
»不为NULL:系统会根据参数及地址边界对齐等分配一个合适的地址
–shmflg:
»IPC_RDONLY:附加只读权限,不指定的话默认是读写权限
»IPC_REMAP:替换位于shmaddr处的任意既有映射:共享内存段或内存映射
»SHM_RND:将shmaddr四舍五入为SHMMLBA字节的倍数
•返回值:共享内存段的地址

shmdt

•函数原型:int shmdt(const void *shmaddr);
•函数功能:解除内存映射,将共享内存分离出当前进程的地址空间
•所需头文件:sys/shm.h
•函数参数
–shmaddr:共享内存地址
•TIPS:
–通过fork创建的子进程会继承父进程所附加的共享内存段,父子进程可以通过共享内存进行IPC通信。在exec系统调用中,所有附加的共享内存段都会被分离
–函数shmdt仅仅是使进程和共享内存脱离关系,将共享内存的引用计数减1,并未删除共享内存。
–当共享内存的引用计数为0时,调用shmctl的IPC_RMID命令才会删除共享内存

shmctl

•函数原型: int shmctl (int shmid, int cmd, struct shmid_ds *buf);
•函数功能:获取/设置 共享内存对象属性
•所需头文件:sys/shm.h
•函数参数
–shmid::共享内存的对象ID
–cmd:
»IPC_RMID:删除共享内存段及关联的shmid_ds数据结构
»IPC_STAT:将该内存对象关联的shmid_ds数据结构拷贝到参数buf中
»IPC_SET:使用buf中的数据更新与该共享内存对象相关联的shmid_ds
»SHM_INFO:获取系统共享内存的相关信息
»SHM_LOCK:将一个共享内存段锁进内存,防止被swap出去
»SHM_UNLOCK:将一个共享内存段解锁

共享内存通讯限制

•SHMMNI:系统所能创建的共享内存的最大个数:IPCMNI 32768
•SHMMIN:一个共享内存段的最小字节数 4096
•SHMMAX:一个共享内存段的最大字节数 33554432
•SHMALL:系统中共享内存的分页总数 2097152
•SHMSEG:一个进程允许attach的共享内存段的最大个数

举例

写共享内存

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <strings.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main (int argc, char *argv[])
{
	key_t key = ftok ("./", 513);
    int shm_id;
	shm_id = shmget (key, 4096, IPC_CREAT | 0666);
    printf ("shm_id: %d\n", shm_id);

	char *shm_p = shmat (shm_id, NULL, 0);
	memset (shm_p, 0 , 4096);

	fgets (shm_p, 4096, stdin);

	sleep (30);
	shmctl (shm_id, IPC_RMID, NULL);

	return 0;
}

读共享内存

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <strings.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main (int argc, char *argv[])
{
	key_t key = ftok ("./", 513);
	int shm_id = shmget (key, 4096, 0666);

	char *shm_p = shmat (shm_id, NULL, 0);
	printf ("from SHM:%s", shm_p);

	shmdt (shm_p);

	return 0;
}
发布了349 篇原创文章 · 获赞 6 · 访问量 9732

猜你喜欢

转载自blog.csdn.net/qq_23929673/article/details/100030108