刚开始翻开UNPv2时,看此章节,有点不知所云。内容看似简单,但却是后续多个章节的总领的简单介绍。当学完后续章节再回过头来看看,其实是非常有用的。可以起到一个快速复习的效果。所以一直都没及时打笔记直至将书本知识都过了一遍。现在再看看,知识点都非常亲切,尤其是创建或打开一个IPC对象的逻辑图,真心佩服作者只用一幅图便可以高度概括相应一个模块知识的能力。接下来好好回顾一下,enjoying!
1、Posix IPC介绍
Posix IPC包括Posix消息队列,Posix信号量,Posix共享内存区。其共同属性有:用于标识的路径名、打开或创建时指定的标志以及访问权限。下表所附相应函数:
消息队列 | 信号量 | 共享内存区 | |
头文件 | <mqueue.h> | <semaphore.h> | <sys/mman.h> |
创建、打开或删除IPC的函数 | mq_open mq_close mq_unlink |
sem_open sem_close sem_unlink |
shm_open |
shm_unlink | |||
sem_init sem_destroy |
|||
控制IPC操作的函数 | mq_getattr mq_setattr |
ftruncate fstat |
|
IPC操作函数 | mq_send mq_receive mq_notify |
sem_wait sem_trywait sem_post sem_getvalue |
mmap munmap |
IPC名字:在Unix中,可通过指定相应的文件名即可。
2、创建与打开IPC通道
mq_open、sem_open和shm_open三个函数创建或打开一个IPC对象的函数(具体函数参见后面章节所写的笔记),其第二个参数oflag是指定怎样打开所请求的对象。其取值参见下表:
说明 | mq_open | sem_open | shm_open |
只读 只写 读写 |
O_RDONLY O_WRONLY O_RDWR |
O_RDONLY | |
若不存在则创建 排他性创建 |
O_CREAT O_EXCL |
O_CREAT O_EXCL |
O_CREAT |
O_EXCL | |||
非阻塞模式 若已存在则截短 |
O_NONBLOCK |
O_TRUNC |
标志说明
O_CREAT 若不存在则创建由函数第一个参数所指定名字的消息队列、信号量或共享内存区对象(同时检查O_EXCL标志)
创建一个新IPC时,至少需要另外一个称为mode的参数。该参数指定权限位,即S_IRUSR、S_IWUSR、S_IRGRP、S_IWGRP、S_IROTH、S_IWOTH,这此常通常放在<sys/stat.h>或<bits/stat.h>
O_EXCL 如果该标志和O_CREAT一起指定,那么IPC函数只在所指定名字的消息队列、信号量或共享内存区对象不存在时才创建新的对象。如果该对象已存在而且指定了O_CREAT|O_EXCL,那么返回一个EEXIST错误(一般可忽视它)。
O_NONBLOCK 该标志使得一个消息队列在队列为空时的读或队列填满时的写不被阻塞。
O_TRUNC 如果以读写模式打开一个已存在的共享内存区对象,那么该标志将使得该对象的长度被截成0.
下图是打开或创建一个IPC对象的逻辑图:
3、IPC权限
权限位与IPC类型的每个对象相关联,就像它们与每个Unix文件相关联一样。
当同样由XXX_open函数打开一个已存在的消息队列、信号量或共享内存区对象时,将基于如下信息执行权限测试:
i、创建时赋予该IPC对象的权限位;
ii、所请求的访问类型(O_RDONLY、O_WRONLY或O_RDWR);
iii、调用进程的有效用户ID、有效组ID以及各个辅助组ID(若支持的话)。
大多数Unix内核按如下步骤执行权限测试。
i、如果当前进程的有效用户ID为0(超级用户),那就允许访问。
ii、在当前进程的有效用户ID等于该IPC对象的属主ID的前提下,如果相应的用户访问权限位已设置,那就允许访问,否则拒绝访问。
此处相应的访问权限位的意思是:如果当前进程为读访问而打开该IPC对象,那么用户读权限位必须设置;如果当前进程为写访问而打开该IPC对象,那么用忘掉写权限位必须设置。
iii、在当前进程的有效组ID或它的某个辅助组ID等于该IPC对象的组ID的前提下,如果相应的组访问权限位已设置,那就允许访问,否则拒绝访问。
iv、如果相应的其他用户访问权限位已设置,那就允许访问,否则拒绝访问。
上述4点按顺序尝试,直至通过为至,否则拒绝访问。
以上知识点来均来自steven先生所著UNP卷二(version2),刚开始学习网络编程,如有不正确之处请大家多多指正。