进程间通信IPC操作记录

1. 共享内存

1.1 创建

int shmget( key_t key, size_t size, int shmflg );
  • key : 共享内存的键值, 用于标识共享内存, 可用ftok()函数生成或自己指定
    • 若key选择为IPC_PRIVATE或者0, 则每次生成的共享内存区域由操作系统决定, 即每次运行共享内存的实际位置都是不同的, 这样, 该共享内存只能被有亲缘关系的进程所调用(因为无法通过id号搜索);
  • size : 共享内存的大小, 为内存页大小的整数倍最佳
  • shmflg : 共享内存的创建方式和权限等标志, 一般格式为: 创建方式宏 | 八进制权限
    • IPC_CREAT : 创建一片新区域, 如果不启用此宏, 则会根据key值查找对应的共享内存段
    • IPC_EXCL : 一般与IPC_CREAT连用, 若指定共享内存已经存在, 则调用失败
    • SHM_HUGE_2MB, SHM_HUGE_1GB: 以大页模式创建共享内存, 需要修改系统文件解除限制
  • return : 成功返回共享内存标识符shmid, 失败-1

1.2 建立映射

void *shmat( int shmid, const void *shmaddr, int shmflg );
  • shmid : 映射目标共享内存的id号
  • shmaddr : 为指定映射对于地址, 一般设置NULL即可, 系统会自动寻找最合适的地址
  • return : 建立映射后的内存指针, 一般需强制类型转化

1.3 解除映射

int shmdt( const void *p );
  • return : 解除传入指针对对应共享内存的映射, 成功返回0, 失败返回1, 并置errno

1.4 状态控制

int shmctl( int shmid, int cmd, struct shmid_st *buf );
  • cmd : 控制方式标识, 根据不同的定义, 后方传入的结构体指针buf有不同作用, 常用的有如下宏定义:
    • IPC_STAT : 把共享内存相关状态放到buf中
    • IPC_SET : 读取buf的数据给共享内存更改比如权限,大小等参数
    • IPC_RMID : 销毁该共享内存, 选择该选择则buf参数置NULL即可
      • 注意: 共享内存不会立即被销毁, 只有当映射到其上的操作都完成释放后才会真正销毁
  • buf : 需要用户自定义的指向shmid_st结构体的指针

2. 信号量

2.1 创建

int  semget( key_t key, int nsems, int semflg );
  • key : 键值, 与shmget相同
  • nsems : 创建信号量的个数
  • semflg : 信号量创建相关的标识, 与shmget类似, 有格式 创建方式宏 | 八进制权限
    • 常用宏定义也为 IPC_CREATIPC_EXCL
  • return : 成功返回信号量的标识符semid, 失败返回-1

2.2 状态控制

int semctl( int semid, int semnum, int cmd, ... );
  • semid : 信号量集的id
  • semnum : 欲获取或改变状态的信号量标号, 从0开始计, 若有复数个操作对象, 置0即可
  • cmd : 状态控制命令, 一般通过宏来指定
    • 与shmctl类似的IPC_xxx系列宏
    • GETVAL : 指定该宏后, 获取semnum对应的信号量值, 并作为返回值返回
    • GETALL/SETALL : 批量获取/设置信号值量的状态, 需要传递第四个参数
    • SETVAL : 设置第semnum个信号量的状态, 通过第四个参数传入
  • 可选参数: union semun : 为结构体, 用于传入传出
    • int val : cmd为SETVAL时, 表示为对应信号量设置的值
    • struct sem_id *buf : cmd为IPC_STAT或IPC_SET时, 对信号量集修改的值
    • unsigned short *arr : cmd为GETALL或SETALL时, 批量获取/设置操作信号量值需要的数组
    • struct seminfo *__buff : cmd为IPC_INFO时, 作为传入传出参数的结构体

2.3 信号量操作

int semop( int semid, struct sembuf *sops, size_t nsops );
  • semid : 信号量集的id
  • struct sembuf *sops : 对信号量进行操作的结构体
    • unsigned short sem_num : 欲操作的信号量的标号数
    • short sem_op : 对信号量的具体操作, 即加减信号量值
    • short semflg : 一些额外的特性标志
      • SEM_UNDO : 当进程意外或主动退出而未释放信号资源时, 自动将其释放
  • nsops : 信号量集中信号量的个数

3. 消息队列

3.1 创建

int msgget( key_t key, int msgflg );
  • 各参数和返回值与shmget和semget相同

3.2 发送数据

int msgsnd( int msgid, const void *msgp, size_t msgz, int msgflg );
  • struct msgbuf *msgp : 一个指向结构体的指针, 用于设置传递消息内容相关
    • long mtype: 标记消息类型, 其值必须大于0
    • char mtext[1]: 消息的内容, 这里表示为一个字节长度, 实际使用时需要对其进行重写, 选择合适的长度
  • size_t : msgz: 传递消息的字节数, 即strlen(mtext)
  • msgflg : 标志位, 一般置为0
  • return : 成功返回0, 失败返回-1

3.3 读取数据

ssize_t msgrcv( int msgid, void *msgp, size_t msgz, long msgtyp, int msgflg );
  • msgid : 消息队列的标识符号
  • msgp : 用于取得消息队列消息的结构体缓冲区, 注意这里需要重载一个类似msgsnd函数中的struct msgbuf结构体用于读取
  • msgz : 最大可读入的字节数, 即sizeof(msgp)
  • msgtyp : 指定读取的消息类型
    • 若指定为0, 则无差别地读取消息队列中的数据
    • 若指定为正整数, 则按队列顺序读取类型为该类型的数据
    • 若指定为负整数, 则按队列顺序读取类型号小于等于其绝对值的数据
  • msgflg : 标志位, 一般置为0
  • return : 成功返回接受到的字节数, 失败返回-1
上一篇:IPC$远程植入木马


下一篇:Android IPC 之服务端回调