svipc - System V interprocess communication mechanisms

linux实现的System V interprocess communication (IPC)机制包含消息队列(message queues),信号集(semaphore sets),和共享内存(shared memory segments)。

man 7 svipc

在新的应用中很少会用到System V IPC,因为它已经被POSIX IPC取代了。但编写老程序时仍可能用到。

像管道一样,IPC存在于内核(实际上是内核内存)而不是像FIFO一样存在于文件系统中。IPC的集中结构有时合起来叫做IPC对象(其实是信号灯、消息队列和共享内存)。

每个对象都通过它的标识符来引用和访问,标识符是一个正整数,它唯一地标识出对象本身和它的类型。每个标识符的类型都是唯一的,但同一标识符的值可以用于一个消息队列、一个信号灯和一个共享内存区。标识符称为该结构上所有其他操作的句柄。IPC结构标识符不想文件描述符那样使用较小的正整数。实际上,随着结构的创建和删除,标识符的值(正式的名称叫做槽使用顺序号)会不断增加直至达到一个最大值为止,然后再转回到0并重新开始。在linux系统中,标识符声明为整数,所以它的值最大可能为65535。

每个IPC结构都有get函数创建,在创建了一个IPC机构之后,使用同一个关键字(key)的get函数的后续调用不会创建新结构,但返回和现在结构相关的标识符。这可以让两个或两个以上的进程用同一关键字key调用get函数以建立一条IPC通道。

接下来的问题是怎样确保所有要使用同一IPC结构的进程都使用相同的关键字。一种方法为,实际创建结构的进程给get函数传递IPC_PRIVATE关键字,这能保证创建一个新结构。然后创建IPC结构的进程把返回的标识符保存在其他进程能够访问的文件系统中。在父进程fork或exec一个子进程的场合,父进程可以把返回的标识符作为一个参数传递给创建子进程的函数exec。

另一种传递关键字的方法是把它保存在公共的头文件中,这样一来所有包含了这个头文件的程序都能够访问到相同的关键字。这种方法引出的一个问题,没有进程直到它是正在创建一个新结构呢还是只访问已经由其他进程创建好的结构。这种方法带来的另外一个问题是关键字可能已经被另外一个无关的程序使用了。结果使用这个关键字的进程必须包含处理这种可能性的代码。

第三种方法是用ftok函数,这个函数接受一个路径名和一个称为项目标识符的单个字符作为参数,返回一个关键字可以传递给get函数。有程序员保证所有的进程实现直到路径名和项目标识符。你可以使用前面提到过的方法之一:在公共的头文件中包含路径名和项目标识符,或者把他们保存在预定义的配置文件中。

不幸的是,ftok有个严重的缺陷:它不能保证产生唯一的关键字,这一来出现了和前面讨论的第二种方法一样的问题。在下列情况下,ftok生成唯一的关键字:

>>当两个不同的符号链接到同一文件上。

>>当路径名的索引节点的前16个比特位具有相同的值。

>>当系统带有两个相同次设备号的硬盘时,在系统由多个磁盘控制器的情况下才会出现。主设备号不相同,但次设备号可以相同。

考虑到linux的ftok实现有弱点,所以强烈建议读者不使用它并且忽略它。

System V IPC有几个缺点,第一,和它提供的好处相比,其编程接口过于复杂。第二,IPC结构比其他资源,比如系统能够支持的文件数量或系统允许的活动进程数目等受到的限制大的多。第三,尽管是一种受限资源,但IPC结构却没有保留一个引用计数(它是一个记录使用结构的进程数目的计数器),因此System V IPC没有回收被丢弃的IPC结构的自动机制。最后,如前面所述,IPC结构只存在于内核中,文件系统不知道他们。因此,对他们的I/O操作需要学习另外一种编程接口。没有文件描述符,你不能通过系统调用select使用多路复用的I/O。如果进程需要等待IPC结构上的I/O操作,它必须使用某种忙等待循环。一个忙等待循环--持续检查某些变化条件的循环--几乎在任何时刻都是一种糟糕的编程习惯,因为它不必要的消耗了CPU周期。在linux下,忙等待循环特别有害,有几种方法,比如阻塞I/O、使用系统调用select和信号来实现非忙等待的循环。

推荐使用POSIX IPC

IPC之SystemV的更多相关文章

  1. linux同步与通信

    这几天读完了UNP v2,对进程间通信与同步的方式有所了解,现对主要的知识点总结如下: 根据出现的历史,先有的管道,FIFO,信号,然后是systemV IPC,再是后来的Poxis IPC,syst ...

  2. Linux进程IPC浅析[进程间通信SystemV共享内存]

    Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到 ...

  3. IPC 机制简介

    IPC 机制简介 概述 在Unix早期发展中,做出重大贡献的两大主力Bell实验室和伯克利大学(BSD)在IPC(InterProcess Communication)方面的侧重点有所不同.前者对Un ...

  4. 进程间通信——XSI IPC之消息队列

    进程间通信XSI IPC有3种:消息队列.共享内存.信号量.它们之间有很多相似之处,但也有各自的特殊的地方.消息队列作为其中比较简单的一种,它会有些什么东西呢,来一起探讨探讨.. 消息队列结构 消息队 ...

  5. 深入理解Android IPC机制之Binder机制

    Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有的进程间通信IPC手段包括(Internet Process Connection): 管道(Pipe).信号(Sign ...

  6. 20155239吕宇轩 Linux下IPC机制

    20155239吕宇轩 Linux下IPC机制 - 共享内存 原理:把所有需要使用的共享数据都存放在共享内存 区域中,任何想要访问这些共享数据的进程都必须在自己的进程地址空间中新增加一块内存区域,用来 ...

  7. IPC之共享内存

    man 7 shm_overview shm_overview - Overview of POSIX shared memory. 同样,SystemV实现的共享内存是旧的机制,但应用广泛:Posi ...

  8. System v和posix的IPC对比

    之前有一篇关于共享内存的System V和Posix的对比: http://www.cnblogs.com/charlesblc/p/6261469.html POSIX(Portable Opera ...

  9. 【linux】系统编程-3-system-V IPC 信号量

    目录 前言 5. 信号量 5.1 概念 5.2 工作原理 5.3 操作函数 5.3.1 semget() 5.3.2 semop() 5.3.3 semctl() 5.4 例程 参考: 前言 原文链接 ...

随机推荐

  1. 解决phpcms使用php7.1.9时修改后台菜单错误 "[] operator not supported for strings"错误提示

    出现这个错误提示是因为 $array 在初始化的时候是一个字符串,在下面使用的时候作为数组使用,php7.x版本并没有将$array自动转换为 数组而是以字符串存在"[]"作为了运 ...

  2. SQL Server CPU时间和占用时间及优化

    如何测试sql语句执行时间 在MSSQL Server中通过查看SQL语句执行所用的时间,来衡量SQL语句的性能. set statistics profile on set statistics i ...

  3. 【Python】装饰器实现日志记录

    好的日志对一个软件的重要性是显而易见的.如果函数的入口都要写一行代码来记录日志,这种方式实在是太低效了,但一直没有找到更好的方法.后来用python写一些软件,了解到python的装饰器功能时,突然人 ...

  4. stderr重定向

    在测试alljoyn时开启了内部日志,输出太多想重定向到文件中,使用如下命令: ./chat -s aaa >.txt 居然还是打印到屏幕上而不是输出到文件中. 查看alljoyn写日志的代码, ...

  5. Android常用传感器用法一览(2)

    在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用. #define SENSOR_TYPE_ACCELEROMETER       1 //加速度#de ...

  6. 防止继承和覆盖(PHP类)

    可能出现需求:我们不希望继承的类覆盖abstract类中的某个方法. 解决方案:我们可以在某个方法前面加上final关键词,可以防止继承的类覆盖它并实现继承类自己的版本. 继承类仍然可以访问和调用这些 ...

  7. jQuery Recipies - 使用map来过滤对应的元素集

    <table id="tblEmployee" class="normal_table"> <tr> <td>Employe ...

  8. Android NDK 交叉编译C++代码生成.so共享库详细步骤

    Android NDK 交叉编译C++代码生成.so共享库详细步骤 Android NDK 调用c++ stl 模板库(修改android.mk文件) 1  在需要调用模板库的文件前包含头文件:   ...

  9. 一步一步学Spring.NET——1、Spring.NET环境准备

    Spring.NET 1.3.2下载地址:http://down.51cto.com/data/861700 下载后解压 Spring.NET-1.3.2.7z:这个里面有我们须要用到的全部东西. S ...

  10. 字符串在内存中的存储——C语言进阶

    字符串是以ASCII字符NUL结尾的字符序列. ASCII字符NUL表示为\0.字符串通常存储在数组或者从堆上分配的内存中.只是,并不是全部的字符数组都是字符串,字符数组可能没有NUL字符. 字符数组 ...