IPC主要包括:管道,消息队列,信号量,共享内存, 套接字(SOCKET)。

一、IPC对象的持久性

每种IPC机制都会借助一种数据结构,这种数据结构的实例称为该IPC机制的对象(相应的,用于同步互斥的数据结构的实体也可以称为该机制的对象)。理清IPC对象的持久性,有助于理解相应的IPC的工作机制。

1.对象持久性

大致上IPC对象的持久性可以分为三种:

  • 进程持久性:具有这种持久性的对象在持有它的最后一个进程关闭了该对象时就会消失。
  • 内核持久性:具有这种持久性的对象在两种情形下会消失,(1)系统重启(2)它被显式的删除
  • 文件系统持久性:具有这种持久性的对象只有在它被显式删除时才会消失。

下表是常见的IPC对象以及用于同步互斥的对象的持久性

类型

持久性

管道

FIFO

进程持久性

进程持久性

Posix互斥锁

Posix条件变量

Posix读写锁

Fcntl记录锁

进程持久性

进程持久性

进程持久性

进程持久性

System V消息队列

System V信号量

System V共享内存

内核持久性

内核持久性

内核持久性

TCP socket

UDP socket

Unix域socket

进程持久性

进程持久性

进程持久性

从表中看没有一种对象的持久性是文件系统的。这也是合理的,因为很少有进程能不受系统重启的影响;而且使用文件系统持久性也可能会降低该IPC机制的性能。

2.调用fork,exec,_exit对IPC对象及同步互斥对象的影响

类型

fork

exec

_exit

管道和FIFO

子进程获得父进程的所有打开的描述符的拷贝

除非描述符的FD_CLOSEXEC比特被置位了,否则描述符保持打开状态

所有描述符都被关闭,在描述符最后一次被关闭时,管道或FIFO中的数据会被删除

System V信号量

所有的semadj的值在子进程中被设置为0

所有的semadj的值被传递给新的程序

所有的semadj的值被加到相应的信号量上

System V消息队列

没影响

没影响

没影响

System V共享内存

父进程中已连接上的共享内存被子进程保留

去除内存映射

去除内存映射

mmap共享内存

父进程的共享内存被子进程保留

去除内存映射

去除内存映射

Posix互斥锁和条件变量

如果在共享内存中并且设置了进程共享属性则就被共享

除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失

除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失

Posix读写锁

如果在共享内存中并且设置了进程共享属性则就被共享

除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失

除非位于仍被打开的共享内存中并且具有进程共享属性否则就将消失

fcntl记录锁

父进程持有的锁不会被子进程所继承

只要描述保持打开,锁就不会因为exec的动作而变化

所有被进程持有的锁都会被释放

二、System V IPC

System V IPC包含:

  • System V消息队列
  • System V信号量
  • System V共享内存区

System V IPC具有一些共同的属性,使用key_t类型的值作为其名字;每个IPC对象有一个与之关联的ipc_perm结构、IPC权限。

1.System V IPC函数汇总

消息队列

信号量

共享内存

头文件

<sys/msg.h>

<sys/sem.h>

<sys/shm.h>

创建、打开或删除IPC

msgget

semget

shmget

控制IPC操作

msgctl

semctl

shmctl

IPC操作

msgsend

msgrcv

semop

shmat

shmdt

2.key_t键和ftok函数
     三种类型的System V IPC使用key_t值作为他们的名字。头文件<sys/types.h>把key_t这个数据类型定义为一个整数,它通常是一个至少32位的整数。这些整数值通常是ftok函数赋赋予的。
     函数ftok把一个已经存在的路径和一个整数标识符转换为一个key_t值,叫IPC键(IPC key).
ftok典型的实现调用stat函数,然后组合以下三个值:
1. pathname所在文件系统的信息;
2. 该文件在本文件系统内的索引节点号;
3. id的低序8位;
     如果pathname不存在或者当前进程不能访问该文件,则ftok返回-1,另外需要注意的是其pathname用于产生key的文件在使用ftok产生的key的进程运行期间不能被创建和删除,因为每次文件被创建,它会需要一个新索引结点编号,这就会导致下次使用ftok时获得了一个不同的key。

3.ipc_perm结构
     内核给每个IPC对象维护一个信息结构,其内容跟内核给文件维护的信息类似。

struct ipc_perm
{
uid_t uid;//owner的用户ID
gid_t gid;//owner的组ID
uid_t cuid;//creater的用户ID
gid_t cgid;//creater的组ID
mode_t mode;//读写模式
ulong_t seq;//序列号
key_t key;//IPC key
};

4.创建与打开IPC通道
     创建或打开一个IPC对象的三个getXXX函数的都需要一个类型为key_t的IPC键的key值,并且返回一个整数标识符。该标识符不同于ftok函数的id参数。对于key值,应用程序有两种选择:

  • 调用ftok,给它传递pathname和id;
  • 指定key为IPC_PRIVATE,这将保证会创建一个新的、唯一的IPC对象;

三个getXXX函数,都有一个oflag参数,他指定IPC对象的读写权位,并选择是创建一个新的IPC对象还是访问一个已存在的IPC对象,规则如下:
1.key指定为IPC_PRIVATE能保证创建一个唯一的IPC对象。没有一对id和pathname的组合会导致ftok产生IPC_PRIVATE这个键值;
2.设置oflag参数的IPC_CREAT位但不设置它的IPC_EXCL位时,如果指定键的IPC对象不存在,那就创建一个新对象,否则返回该对象;
3.设置oflag参数的IPC_CREAT位和它的IPC_EXCL位时,如果所指定键的IPC对象不存在,那就创建一个新的对象,否则返回一个EEXIST错误,因为该对象已经存在;
4.如果要访问一个已经存在的IPC,就不能指定IPC_PRIVATE标记,因为这是一个特殊的用于创建IPC对象的键值

5.IPC权限
     创建一个新的IPC对象时,以下信息就保存该对象的ipc_perm结构中:
1. oflag参数中某些比特会初始化ipc_perm结构的mode成员。
2. cuid和cgid成员分别设置为调用进程的有效用户ID和有效组ID。这两个成员合称为创建者ID。
3. ipc_perm结构的uid和gid成员也分别设置为调用进程的有效用户ID和有效组ID。这两个成员合称为所有者ID。
     在创建IPC结构时,除seq以外的所有字段都赋初值。以后,可以调用msgctl、semctl或shmctl修改uid、gid和mode字段。为了改变这些值,调用进程必须是IPC结构的创建者或超级用户。

许可权

消息队列

信号量

共享内存

用户读
用户写(更改)

MSG_R
MSG_W

SEM_R
SEM_A

SHM_R
SHM_W

组读
组写(更改)

MSG_R>>3
MSG_W>>3

SEM_R>>3
SEM_A>>3

SHM_R>>3
SHM_W>>3

其他读
其他写(更改)

MSG_R>>6
MSG_W>>6

SEM_R>>6
SEM_A>>6

SHM_R>>6
SHM_W>>6

需要注意的是:

1.创建者ID永远不会改变,但是进程可以通过IPC机制中的IPC_SET命令修改所有者ID。三个getXXX没有使用UNIX的文件创建模式掩码,IPC对象的权限被设置为指定的值。Posxi IPC非常类似文件,但是System V IPC在权限的存储上是与文件系统的不同的,它的权限不受文件创建模式掩码的影响。

2.任意进程要访问一个IPC对象都需要经历两个层级的检查:一个在IPC对象被打开时(检查是否指定了未包含在ipc_perm结构中的模式,因为创建的IPC对象的权限是存在于ipc_perm结构中的),一个在IPC对象被使用时(过程类似于PosixIPC的权限检查)。

6.ipcs和ipcrm程序
     由于System V IPC的三种类型不是以文件系统中路径名标识的,因此使用标准的ls和rm程序无法看到它们,也无法删除他们。不过实现了这些类型IPC的任何系统都提供两个特殊的程序:ipcs和ipcrm。ipcs输出有关System V IPC特性的各种信息,ipcrm则删除一个System V消息队列、信号量集或共享储存区。

7.内核限制
System V IPC的多数实现有内在的内核限制,例如消息队列的最大数目、每个信号量集的最大信号量数等。
另外还存在一些缺点:

  • IPC结构是在系统范围内起作用的,没有访问计数。例如,如果创建了一个消息队列,在该队列中放入了几则消息,然后终止,但是该消息队列及其内容并不被删除。它们余留在系统中直至:由某个进程调用msgrcv或msgctl读消息或删除消息队列,或某个进程执行ipcrm命令删除消息队列;或由正在再启动的系统删除消息队列。
  • 这些IPC结构并不按名字为文件系统所知。因此不能用常规的文件系统函数来存取它们或修改它们的特性。为了支持它们不得不增加了十多个全新的系统调用(msgget、semop、shmat等)。不能用ls命令见到它们,不能用rm命令删除它们,不能用chmod命令更改它们的存取权。于是,也不得不增加了全新的命令ipcs和ipcrm。
  • 这些IPC不使用文件描述符,所以不能对它们使用多路转接I/O函数:select和poll。

UNIX环境高级编程——IPC总结的更多相关文章

  1. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  2. (十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC)

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  3. Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级 ...

  4. (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  6. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  7. (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  8. (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

随机推荐

  1. json转化为对象数组

    1.ascx传值给aspx aspx页面 <%@ Page Title="" Language="C#" MasterPageFile="~/_ ...

  2. 一看你就懂,超详细java中的ClassLoader详解

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普通的Java开发者其实用到的不多,但对于某些框架开发者来说却非常常见.理解ClassL ...

  3. 操作系统内存管理之 内部碎片vs外部碎片

    外部碎片:因为行程持续地被载入与置换,使得可用的记忆体空间被分割成许多不连续的区块.虽然记忆体所剩空间总和足够让新行程执行,却因为空间不连续,导致程式无法载入执行.内部碎片:发生在以固定长度分割区来进 ...

  4. [ Java学习基础 ] Java异常处理

    一.异常概述 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的.比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用Sys ...

  5. 剑指架构师系列-spring boot的logback日志记录

    Spring Boot集成了Logback日志系统. Logback的核心对象主要有3个:Logger.Appender.Layout 1.Logback Logger:日志的记录器 主要用于存放日志 ...

  6. 含有分类变量(categorical variable)的逻辑回归(logistic regression)中虚拟变量(哑变量,dummy variable)的理解

    版权声明:本文为博主原创文章,博客地址:,欢迎大家相互转载交流. 使用R语言做逻辑回归的时候,当自变量中有分类变量(大于两个)的时候,对于回归模型的结果有一点困惑,搜索相关知识发现不少人也有相同的疑问 ...

  7. UCSC下载ENCODE数据

    ENCODE数据库用于存放基因组原件,所有的测序数据(原始数据以及每一步处理后的数据以及最终的结果)都是开放下载的.假如说去官网下载的话会比较麻烦,这里可以通过UCSC的数据库下载(真的是神器啊)!下 ...

  8. 从输入url到页面返回到底发生了什么

    1. 前言 Google应该是开发者平日里用得最多的网站之一,今早笔者在浏览器地址栏里键入www.google.com的时候,突然想了解下这背后的网络通信过程究竟是怎么样的.毕竟自己也算是一名Web开 ...

  9. Java内存泄漏分析系列之四:jstack生成的Thread Dump日志线程状态

    原文地址:http://www.javatang.com Thread Dump日志的线程信息 以下面的日志为例: "resin-22129" daemon prio=10 tid ...

  10. OC基础之可循环滚动并突出中间图片,并且可点击

    前两天一哥们儿让我帮他写一下:可循环滚动并突出中间图片,并且可点击的一种滑动视图的效果,今天放在这里给大家展示一下,具体文字代码中都有注解,代码还有待完善,不喜勿喷,转载请注明,下载请点星,谢谢~ - ...