标签:style color get strong 使用 文件
一、进程间通信(IPC):Unix / Linux 系统基于多进程,进程和进程之间数据的交互。2.共享内存、消息队列和信号量集遵循相同的规范,统称为 XSI IPC。
------------------------------------------
二、管道:一种仅做为交互媒介的IPC的特殊的文件,不存储任何的数据,文件名后缀.p,只有在有读且有写操作时才能畅通,否则阻塞。
1.管道有两种用法:有名管道和无名管道。
1)有名管道:可用于所有进程之间的交互。无名管道:只能用于fork()创建的父子进程之间的交互。
2)有名管道:程序员创建管道文件进行IPC。无名管道:系统创建和维护管道文件进行IPC。
2.使用有名管道的步骤:
a.创建管道文件:mkfifo命令|||mkfifo("...")函数 【touch 命令和 open()函数都无法创建管道文件】。
b.像读写普通文件一样操作管道文件。
c.可以删除管道文件。
注意:open 一个管道文件,权限不要用 O_RDWR。
------------------------------------------
三、XSI IPC 的通用规范:每个 IPC 都由一个内部的ID做唯一的标识。内部ID的获取,需要借助与之对应外部key(类型 key_t)。
1. key 获取的三种方式:
a 使用宏 IPC_PRIVATE 做 key,但外部无法获取,基本不用。
b 使用ftok()获取一个 key。
c 在头文件中为每个IPC统一分配唯一的 key。
2.通过key 获取内部 id:msgget(2)、semget(2)、shmget(2) //int msgget(key_t key, int msgflg);
3.每种IPC 结构都提供了一个 xxxctl()函数(查询、修改和删除)。
4.所有IPC 结构都是内核管理,不使用时需要手工删除。
5.IPC 结构的相关命令:
ipcs - 查询当前的 IPC 结构
ipcrm - 删除当前的 IPC 结构 (用 id 删除)
选项:-a 所有 IPC 结构
-m 共享内存 Shared Memory Segments
-q 消息队列 Semaphore Arrays(更常用)
-s 信号量集 Message Queues
------------------------------------------
四、共享内存:以一块共享的物理内存做媒介。共享内存虽然速度最快(效率最高的IPC),但当多个进程同时写数据时,数据会互相覆盖,导致混乱。
1.共享的实现(通常情况下,两个进程无法直接映射相同的内存。):
a)内核先拿出一块物理内存,内核 负责管理。
b)允许所有进程对这块内存进行映射。则两个不同的进程,就可以映射到相同的物理内存上,从而实现信息的交互。
2.编程步骤:
a)获取 key。
b)使用 shmget()函数用key创建 / 获取内部的 ID。
c)使用 shmat()挂接共享内存(映射)- shm_nattch; /* No. of current attaches */可以像正常操作一样使用共享内存。
d)使用 shmdt()脱接共享内存(解除映射)。
e)如果确定已经不再使用,可以使用shmctl()删除共享内存。
3.相关函数:
1)获取key:key_t ftok(const char *pathname, int proj_id);/* ftok()函数使用给定的文件名(必须存在,可访问的文件)和proj_id的低8位(必须非零)来生成key_t类型System
V IPC的key,适用于msgget(2), semget(2)或者shmget(2)。*/
2)获取(创建)内部ID,并设置共享内存大小:int/*ID */ shmget(key_t key, size_t size/*共享内存的大小*/,
int shmflg/*flag获取时:0;新建时:IPC_CREAT|0666(权限)*/);
3)挂载内存:void *shmat(int shmid, const void *shmaddr, int shmflg);(和mmap相似)如:void *shmat(int shmid, 0, 0);/*If shmaddr is NULL, the system chooses a suitable (unused) address at which to attach the
segment. */ /* Return:On success shmat() returns the address of the attached shared memory segment; on error (void *) -1 is returned。*/
4)脱接内存:int shmdt(const void *shmaddr);//shmaddr 是shmat()的返回值,首地址(虚拟)。
5)查询、修改和删除共享内存:int shmctl(int shmid, int cmd, struct shmid_ds *buf /*结构体指针*/ );
cmd 参数:1)IPC_STAT - 查询 2)IPC_SET - 修改 3)IPC_RMID - 按ID 删除IPC 结构
查询时:会把共享内存的信息放入第三个参数。
修改时:只有用户id、组id和权限可以修改,大小不可修改。
删除时:第三个参数给 0 即可。删除共享内存时,挂接数必须为 0 ,才能真正删除,否则删除只是做一个标记,等挂接数为 0 时,才能真正删除。
------------------------------------------
五、消息队列(FIFO):存放消息的队列。
1.消息队列实现:数据先封入消息中,然后再把消息存入队列。一般情况下,队列有满有空。可以解决多个进程同时写数据的问题。
2.编程步骤:
a)得到外部的 key。
b)使用msgget()函数用key 创建 / 获取一个消息队列ID。
c)把数据 / 消息 存入队列 或 从队列中取出。//函数msgsnd()存入 / msgrcv()取出/*
IPC_NOWAIT 无等待,直接返回 */
d)如果不再使用消息队列,可以msgctl()删除。
3.相关函数:
int msgsnd(int msqid/*消息队列的ID*/, const void *msgp, size_t msgsz, int msgflg);
a)msgp:消息的首地址,其中消息分为有类型消息(更规范)和无类型消息。
b)有类型消息结构:
struct Msg{ // 结构的命令可以自定义
long mtype;//消息的类型,必须大于 0/*可通过定义宏的方式*/,接收消息时,可以按照类型有选择的接受消息
... ... //数据区域,可以任意写
}
c)size:是数据区域的大小,不包括 mtype的大小(有些时候也包括,规范情况下,不包括)。
d)flag:选项,可以是 0 代表阻塞(队列满了),也可以是IPC_NOWAIT 代表非阻塞(队列满了直接返回错误)。
e)成功返回 0,失败返回 -1。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
a)msgtyp 可以让接收者有选择的接收消息,值可能是:
0 - 接收任意类型的消息(第一个,先入先出)。
>0 - 接收类型为 mtype 的特定消息。
<0 - 接收类型 小于等于 mtype 绝对值的消息,从小到大接收。
b)成功返回接收到的数据大小,失败返回 -1。
UnixC——进程间通信(IPC),布布扣,bubuko.com
标签:style color get strong 使用 文件
原文地址:http://blog.csdn.net/u012627502/article/details/30990559