IPC对象通信:
消息队列(使用比较少)
共享内存(这里只讨论共享内存)
信号量集 (一般线程使用信号量比较多)
IPC对象操作通用框架:
key值 ==> 申请 ==》读写 ==》关闭 ==》卸载
key值:===》唯一键值,内核分配了一块共享内存后,用户无法直接使用,只能通过key值来间接使用
共享内存:
ftok()
ftok()创建临时键值。(三板斧,ftok,shmget,shmat,前一个函数的返回值都将作为下个函数的参数之一)
#include <sys/types.h>
#include <sys/ipc.h>
//pathname可取值:"/etc",'!'
key_t ftok(const char *pathname, int proj_id); //key_t 实际上是unsigned int
功能:通过该函数可以将pathname指定的路径用来以
proj_id生成唯一的临时键值。
参数:pathname 路径+名称===》任意文件,只要不会
被删除重建即可。
proj_id 整形的数字,一般用ASCII码的单字符
表示与参数1的运算。
返回值:成功 返回唯一键值
失败 -1;
ipcs -a 查询共享内存,信号量集,消息队列
ipcrm -s 删除信号量集
-m 删除共享内存
共享内存 ===》效率最高的进程间通信方式
操作流程:
key ==》申请对象 ==》映射对象==》读写对象
==》撤销映射 ==》删除对象
shmget()
申请对象:shmget()
#include <sys/ipc.h>
#include <sys/shm.h>
ps aux|grep a.out
share memory get IPC_CREAT|0666
int shmget(key_t key, size_t size, int shmflg);
功能:使用唯一键值key向内核提出共享内存使用申请
参数:key 唯一键值
size 要申请的共享内存大小
shmflg 申请的共享内存访问权限,八进制表示
如果是第一个申请,则用IPC_CREAT
如果要检测是否存在,用IPC_EXCL
返回值:成功 返回共享内存id,一般用shmid表示
失败 -1;
shmat()(share memory attach,映射对象)
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将指定shmid对应的共享内存映射到本地内存。
参数:shmid 要映射的本地内存
shmaddr 本地可用的地址,如果不确定则用NULL,表示
由系统自动分配。
shmflg
0,表示读写(也可以写成!SHM_RDONLY)
SHM_RDONLY,只读
返回值:成功 返回映射的地址,一般等于shmaddr
失败 (void*)-1
读写共享内存:类似堆区内存的直接读写:
shmdt()(撤销映射)
int shmdt(const void *shmaddr);
功能:将本地内存与共享内存断开映射关系。
参数:shmaddr 要断开的映射地址。
返回值:成功 0
失败 -1;
需要注意的是,分离共享内存段并不会销毁它,共享内存段仍然存在于系统中,直到显式删除或系统重启。
其作用在多个进程同时关联该共享内存时,某一进程不需要使用后,断开与该共享内存的关联关系,下面的shmctl函数在关联关系为0时,才能够成功删除该共享内存
shmctl()
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:修改共享内存属性,也可以删除指定的共享内存对象。
参数:shmid 要删除的共享内存对象
cmd IPC_RMID 删除对象的宏
IPC_STAT: 获取共享内存段的状态信息,并将其存储在 buf 指向的结构中。
IPC_SET: 根据 buf 指向的结构中的值设置共享内存段的属性。
buff NULL 表示只删除对象。
返回值:成功 0
失败 -1
二进制清零函数(将整段内存清零):
bzero()
void bzero(void *s, size_t n)
参数:s是指向要清零的内存区域的指针,
n是要清零的字节数。
功能:bzero()函数通常用于初始化一段内存区域,例如清空一个字符数组或结构体变量。它与memset()函数类似,但是bzero()函数只能将内存区域清零,而memset()函数可以将内存区域设置为任意指定的值。(memset(p,0,1024)== bzero(p,1024))
memset()
void *memset(void *s, int c, size_t n)
参数:s是指向要填充的内存块的指针,
它的作用是告诉函数要填充的一块空间的起点在哪.
c是要填充的值,通常是一个无符号字符,
它的作用是告诉函数这块空间要填充成哪个值.
n表示要填充的字节数,
它的作用是告诉函数一共需要将多少个字节的空间设置成要填充的值.
函数的返回值类型是void*(无类型指针),
它的作用是在函数运行结束后返回这块空间的起始地址.
memcpy()
void * memcpy ( void * destination, const void * source, size_t num );
参数:destination指向拷贝的目的地内存块,
它的作用是为函数提供目的地的内存块首地址
source指向拷贝数据的来源内存块,
它的作用是为函数提供拷贝源头内存块首地址,
其被const修饰,表示其指向的内容不可修改
num表示要拷贝数据的字节数
函数的返回值类型是无类型指针(void*),返回destination的首地址