0.System V IPC机制:
①.IPC对象包含:共享内存、消息队列和信号灯集。
②.每个IPC对象有唯一的ID。
③.IPC对象创建后一直存在,直到被显示地删除。
④.每一个IPC对象有一个关联的KEY。(其他进程通过KEY访问对应的IPC对象)
⑤.ipcs(显示系统所有的IPC对象)、ipcrm
一. 生成KEY值 - ftok
功能:
成功时返回(合法的key值),失败时返回(EOF)。
若传入的参数一样,那么得到的key值也一样
参数:
path:存在且可访问的文件的路径
proj_id:用于生成key的数字,不能为0,一般为字符常量
int key_t ftok(const char *path,int proj_id);
int main(int argc,char *argv[])
{
key_t key;
key = ftok(".",'a');
if(-1 == key)
{
perror("key error");
exit(-1);
}
}
二.共享内存
0.特点
①.共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。
②.共享内存在内核空间创建,可被进程映射到用户空间访问,使其灵活。
③.由于多个进程可同时访问共享内存,因此需要同步和互斥机制配合使用。
④.共享内存的大小有限制
1.创建/打开共享内存 - shmget()
功能:
创建/打开共享内存对象
成功时返回(共享内存的id),失败时(EOF)
参数:
key:和共享内存关联的key,IPC_PRIVATE或由ftok生成。
size:共享内存的大小,单位为字节。
shmflg:共享内存标志位 IPC_CREATE | 0666(不存在就创建,存在了就打开)。
int shmget(key_t key,int size,int shmflg);
示例1:创建一个私有的共享内存,大小为512字节,权限为0666
int shmid;
shmid = shmget(IPC_PRIVATE,512,0666);
if(0 > shmid)
{
perror("shmget error");
exit(-1);
}
示例2:创建/打开一个和key关联的共享内存,大小为1024字节,权限为0666
key_t key;
int shmid;
/* 1.先生成key(相关的进程调用ftok时,传入相同的参数才能得到相同的key) */
key = ftok(".",'m');
if(-1 == key)
{
perror("ftok");
exit(-1);
}
/* 2.获取共享内存 */
shmid = shmget(key,1024,IPC_CREATE | 0666);
if(0 > shmid)
{
perror("shmget");
exit(-1);
}
2.映射共享内存 - shmat
功能:
映射共享内存;
成功时返回(映射后的地址),失败时返回((void *)-1),通过指针访问共享内存,指针类型取决于共享内存中存放的数据的类型;
参数:
shmid:要映射的共享内存的id。
shmaddr:指定映射后的地址(通常传入NULL),NULL表示由系统自动映射。
shmflg:标志位,0表示可读写;SHM_RDONLY表示只读。
void *shmat(int shmid,const void *shmaddr,int shmflg);
示例1:在共享内存中存放键盘输入的字符串
char *addr; //保存映射后的首地址
int shmid;
/* 映射共享内存 */
addr = (char *)shmat(shmid,NULL,0);
id((char *)-1 == addr)
{
perror("shmat");
exit(-1);
}
fgets(addr,N,stdin);
3.读写共享内存
操作映射的共享内存的地址
4.撤销共享内存映射 - shmdt
功能:
撤销共享内存映射
成功时返回(0),失败时返回(EOF)
参数:
shmaddr:映射共享内存的首地址
int shmdt(void *shmaddr);
5.共享内存控制 - shmctl
功能:
控制共享内存。
成功时返回(0),失败时返回(-1)并设置errno。
参数:
shmid:要操作的共享内存的id。
cmd :要执行的操作
IPC_STAT:获取当前共享内存的属性(大小,关联的key值,权限等),存入到 shmid_ds *buf中
IPC_SET :将属性(先在shmid_ds *buf中填充)设置到共享内存的id中
IPC_RMID:删除一个共享内存的id
buf:保存或设置共享内存属性的地址
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
6.删除共享内存对象 - shmctl
用shmctl来删除共享内存对象(应该由最后一个进程来执行此操作)
功能:
添加删除标记,当每一个进程都撤销共享内存映射后(nattach == 0)才真正的删除。
shmctl(shmid,IPC_RMID,NULL);