共享内存知识点整理

ipcs用于输出消息队列,信号量,共享内存的使用信息
ipcs -m只输出共享内存
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status     
0x0103c005 49446938   dmslcclcj 644        1028       1

perms表示权限其实是9位二进制,rwxrwxrwx

shmget函数申请了共享内存后,程序结束后不会自动释放
shmat函数attach上共享内存后,程序结束后自动detach

ipcrm用于释放消息队列,信号量,共享内存
ipcrm -m 49446938 根据id释放共享内存
ipcrm -M 0x0103c005 根据key释放共享内存

系统建立IPC通讯 (消息队列、信号量和共享内存) 时必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
key_t ftok( const char * fname, int id )
id是子序号。
在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。

如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,
换算成16进制为0x26,则最后的key_t返回值为0x26010002。
查询文件索引节点号的方法是: ls -i

项目里使用的指定文件为用户下的bin目录,或者config目录,因为这些目录一般不会随便删除改变

用于Linux进程通信共享内存。共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。

shmget(得到一个共享内存标识符或创建一个共享内存对象并返回共享内存标识符)
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg)
key为IPC_PRIVATE即0时会建立新共享内存对象
key为大于0的32位整数时视参数shmflg来确定操作。通常要求此值来源于ftok返回的IPC键值
size指定新建的共享内存大小,以字节为单位
shmflg为权限标识,一般传644即创建者可读写,同组的或者其他组的只能读
当传入的为shmflg|IPC_CREAT时,如果内核中不存在键值与key相等的共享内存,
则新建一个共享内存.如果存在这样的共享内存,返回此共享内存的标识符
当传入的为shmflg|IPC_CREAT|IPC_EXCL时,如果内核中不存在键值与key相等的共享内存,
则新建一个共享内存;如果存在这样的共享内存则报错

函数返回共享内存的标识符或者-1表出错。
出错:-1,错误原因存于error中
错误代码
EINVAL:参数size小于SHMMIN或大于SHMMAX
EEXIST:预建立key所指的共享内存,但已经存在
EIDRM:参数key所指的共享内存已经删除
ENOSPC:超过了系统允许建立的共享内存的最大值(SHMALL)
ENOENT:参数key所指的共享内存不存在,而参数shmflg未设IPC_CREAT位
EACCES:没有权限
ENOMEM:核心内存不足

shmat(把共享内存区对象映射到调用进程的地址空间)
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg)
shmid为共享内存的标识符通过shmget获得
shmaddr指定共享内存出现在进程内存地址的什么位置,
直接指定为NULL让内核自己决定一个合适的地址位置,一般传0
shmflg为SHM_RDONLY时,为只读模式,其他为读写模式,一般传0
返回对应的共享内存地址或者-1

fork后子进程继承已连接的共享内存地址。exec后该
子进程与已连接的共享内存地址自动脱离(detach)。
进程结束后,已连接的共享内存地址会自动脱离(detach)

出错:-1,错误原因存于error中
错误代码
EACCES:无权限以指定方式连接共享内存
EINVAL:无效的参数shmid或shmaddr
ENOMEM:核心内存不足

shmdt(断开共享内存连接,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存)
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr)
shmaddr为连接的共享内存的起始地址
返回0或者-1
出错:-1,错误原因存于error中
错误代码
EINVAL:无效的参数shmaddr

shmctl(共享内存管理)
#include <sys/types.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
shmid 共享内存标识符
cmd 为
IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
该命令只有具备以下条件的进程才可以执行
1.进程的用户ID等于shm_perm.cuid或者等于shm_perm.uid
2.超级用户特权进程

IPC_RMID:删除这片共享内存.只有当shmid_ds结构的shm_nattch域为零时,才会真正执行删除命令,
否则不会删除该段,注意此命令的请求规则与IPC_SET命令相同
SHM_LOCK:锁定共享内存段在内存,此命令只能由超级用户请求
SHM_UNLOCK:对共享内存段解锁,此命令只能由超级用户请求

buf 共享内存管理结构体指针。

#include<bits/shm.h>
struct shmid_ds
{
    struct ipc_perm shm_perm;           /* operation permission struct */
    size_t shm_segsz;                   /* size of segment in bytes */
    __time_t shm_atime;                 /* time of last shmat() */
#if __WORDSIZE == 32
    unsigned long int __unused1;
#endif
    __time_t shm_dtime;                 /* time of last shmdt() */
#if __WORDSIZE == 32
    unsigned long int __unused2;
#endif
    __time_t shm_ctime;                 /* time of last change by shmctl() */
#if __WORDSIZE == 32
    unsigned long int __unused3;
#endif
    __pid_t shm_cpid;                   /* pid of creator */
    __pid_t shm_lpid;                   /* pid of last shmop */
    shmatt_t shm_nattch;                /* number of current attaches */
    unsigned long int __unused4;
    unsigned long int __unused5;
};

#include<bits/ipc.h>
struct ipc_perm
{
    __key_t __key;                      /* Key.  */
    __uid_t uid;                        /* Owner's user ID.  */
    __gid_t gid;                        /* Owner's group ID.  */
    __uid_t cuid;                       /* Creator's user ID.  */
    __gid_t cgid;                       /* Creator's group ID.  */
    unsigned short int mode;            /* Read/write permission.  */
    unsigned short int __pad1;
    unsigned short int __seq;           /* Sequence number.  */
    unsigned short int __pad2;
    unsigned long int __unused1;
    unsigned long int __unused2;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值