C语言 NOTE32

邮差的信 提交于 2020-02-06 00:39:33

系统编程之共享内存

在这里插入图片描述



1.创建键值:

  • 头文件:
    #include <sys/types.h>
    #include <sys/ipc.h>
  • 函数原型:
key_t ftok(const char *pathname, int proj_id);
  • 参数分析:
    pathname ---->一般设为当前文件路径"."。
    proj_id ---->编号,主要是为了区分不同的键值。两个进程只要是使用相同的键,那么他们就指向同一个通信模块


使用ipcs -m查看系统的共享内存:
在这里插入图片描述



2.创建共享内存shmid

功能 获取共享内存的 ID

  • 头文件
    #include <sys/ipc.h>
    #include <sys/shm.h>
  • 函数原型
 int shmget(key_t key, size_t size, int shmflg);
参数 分析
key 共享内存的键值
size 共享内存的尺寸(PAGE_SIZE 的整数倍)
shmflg 标志位如下
IPC_CREAT 如果 key 对应的共享内存不存在,则创建之
IPC_EXCL 如果该 key 对应的共享内存已存在,则报错
SHM_HUGETLB 使用“大页面”来分配共享内存
SHM_NORESERVE 不在交换分区中为这块共享内存保留空间
mode 共享内存的访问权限(八进制,如 0644)
  • 返回值
    成功 该共享内存的 ID
    失败 -1
    备注 如果 key 指定为为 IPC_PRIVATE,则会自动产生一个随机未用的新键值


3.映射(解除)共享内存:

功能 对共享内存进行映射,或者解除映射

  • 头文件
    #include <sys/types.h>
    #include <sys/shm.h>
  • 函数原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
参数 分析
shmid 共享内存 ID
shmaddr
shmat( ) 1.如果为 NULL,则系统会自动选择一个合适的虚拟内存空间地址去映射共享内存。2.如果不为 NULL,则系统会根据 shmaddr 来选择一个合适的内存区域。
shmdt( ) 共享内存的首地址
shmflg 0表示可读可写
SHM_RDONLY 以只读方式映射共享内存
SHM_REMAP 重新映射,此时 shmaddr 不能为 NULL
SHM_RND 自动选择比 shmaddr 小的最大页对齐地址
  • 返回值
    成功 共享内存的首地址
    失败 -1


4.从内核中删除共享内存

使用Linux命令删除:ipcsm -m shmid 或 ipcsm -M 键值
使用函数删除
功能 获取或者设置共享内存的相关属性

  • 头文件
    #include <sys/ipc.h>
    #include <sys/shm.h>
  • 函数原型
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • 参数
shmid 共享内存 ID
cmd 操作指令
IPC_STAT 获取属性信息,放置到 buf 中
IPC_SET 设置属性信息为 buf 指向的内容
IPC_RMID 将共享内存标记为“即将被删除”状态
IPC_INFO 获得关于共享内存的系统限制值信息
SHM_INFO 获得系统为共享内存消耗的资源信息
SHM_STAT 同 IPC_STAT,但 shmid 为该 SHM 在内核中记录所有 SHM 信息的数组的下标,因此通过迭代所有的下标可以获得系统中所有 SHM 的相关信息
SHM_LOCK 禁止系统将该 SHM 交换至 swap 分区
SHM_UNLOCK 允许系统将该 SHM 交换至 swap 分区
buf 属性信息结构体指针
  • 返回值
    成功
    IPC_INFO
    内核中记录所有 SHM 信息的数组的下标最大值
    SHM_INFO
    SHM_STAT 下标值为 shmid 的 SHM 的 ID
    失败 -1

1,IPC_STAT 获得的属性信息被存放在以下结构体中:

struct shmid_ds
{
	struct ipc_perm shm_perm; /* 权限相关信息 */
	size_t shm_segsz; /* 共享内存尺寸(字节) */
	time_t shm_atime; /* 最后一次映射时间 */
	time_t shm_dtime; /* 最后一个解除映射时间 */
	time_t shm_ctime; /* 最后一次状态修改时间 */
}

其中权限信息结构体如下:

struct ipc_perm
{
	key_t __key; /* 该 SHM 的键值 key */
	uid_t uid; /* 所有者的有效 UID */
	gid_t gid; /* 所有者的有效 GID */
	uid_t cuid; /* 创建者的有效 UID */
	gid_t cgid; /* 创建者的有效 GID */
	unsigned short mode; /* 读写权限 +
	SHM_DEST +
	SHM_LOCKED 标记 */
	unsigned short __seq; /* 序列号 */
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!