15.1 引言

*进程之间交换信息的方法可以经由fork或exec传送打开文件,或者通过文件系统

*进程之间相互通信的其他技术——IPC(InterProcess Communication)包括半双工管道、FIFO、全双工管道、命名全双工管道、消息队列、信号量、共享存储、套接字、STREAMS

15.2 管道

*管道有两种局限性:(1)历史上,它们是半双工的(即数据只能在一个方向上流动)(2)它们只能在具有公共祖先的进程之间使用

*每当你在管道线中键入一个由shell执行的命名序列时,shell为每一条命令单独创建一进程,然后将前一条命令进程的标准输出用管道与后一条命令的标准输入相连接

*管道是由调用pipe函数而创建的

15.3 popen和pclose函数

*常见的操作是创建一个管道连接到另一个进程,然后读其输出或向其输入端发送数据。为此,标准I/O库提供了两个函数popen和pclose。这两个函数实现的操作是:创建一个管道,调用fork产生一个进程,关闭管道的不使用端,执行一个shell以运行命令,然后等待命令终止

15.4 协同进程

*UNIX系统过滤程序从标准输入读取数据,对其进行适当处理后写到标准输出。几个过滤程序通常在shell管道命令行中线性的连接。当一个程序产生某个过滤程序的输入,同时又读取该过滤程序的输出时,则该过滤程序就称为协同进程(coprocess)

*标准I/O的缓冲机制问题的解决方法是使被调用的协同进程(在本例中是awk)认为它的标准输入和输出都被连接到一个终端

15.5 FIFO

*FIFO有时被称为命名管道。管道只能由相关进程使用,这些相关进程的共同的祖先进程创建了管道。(一个例外是已装配的基于STREAMS的管道)。但是,通过FIFO,不相关的进程也能交换数据。

*FIFO有下面两种用途:

(1)FIFO由shell命令使用以便将数据从一条管道线传送到另一条,为此无需创建中间临时文件

(2)FIFO用于客户进程-服务器进程应用程序中,以在客户进程和服务器进程之间传递数据

15.6 XSI IPC

*有三种IPC我们称作XSI IPC,即消息队列、信号量以及共享存储器,它们之间有很多相似之处

*每个内核中的IPC结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符(identifier)加以引用

*标识符是IPC对象的内部名。为使多个合作进程能够在同一IPC对象上会合,需要提供一个外部名方案。为此使用键(key),每个IPC对象都与一个键相关联,于是键就用作为该对象的外部名

*有多种方法可以使客户进程和服务器进程在同一IPC结构上会合:

(1)服务器进程可以指定键IPC_PRIVATE创建一个新IPC结构,将返回的标识符存放在某处(例如一个文件)以便客户进程取用。键IPC_PRIVATE保证服务器进程创建一个新IPC结构。IPC_PRIVATE键也可用于父子进程关系。父进程指定IPC_PRIVATE创建一个新IPC结构,所返回的标识符在调用fork之后可由子进程使用。接着,子进程又可将此标识符作为exec函数的一个参数传给一个新程序

(2)在一个公用头文件中定义一个客户进程和服务器进程都认可的键。然后服务器进程指定此键创建一个新的IPC结构

(3)客户进程和服务器进程认同一个路径名和项目ID(项目ID是0~255之间的字符值),接着调用函数ftok将这两个值变换为一个键。然后在方法(2)中使用此键。ftok提供的唯一服务就是由一个路径名和项目ID产生一个键

15.7 消息队列

*msgget创建一个新队列或打开一个现存的队列。msgsnd将新消息添加到队列尾端。每个消息包含一个正长整数类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在讲消息添加到队列时,传送给msgsnd。msgrcv用于从队列中取消息。

*每个消息由三部分组成,它们是:正长整型类型字段、非负长度(nbytes)以及实际数据字节(对应于长度)。消息总是放在队列尾端

*若消息队列已满(或者是队列中的消息总数等于系统限制值,或队列中的字节总数等于系统限制值),则指定IPC_NOWAIT使得msgsnd立即出错返回EAGAIN。如果没有指定IPC_NOWAIT,则进程阻塞直到下述情况出现为止:有空间可以容纳要发送的消息;从系统中删除了此队列,或捕捉到一个信号,并从信号处理程序返回。

15.8 信号量

*信号量(semaphore)与已经介绍过的IPC机构(管道、FIFO以及消息队列)不同。它是一个计数器,用于多进程对共享数据对象的访问

15.9 共享存储

*共享存储允许两个或更多进程共享一给定的存储区。因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的一种IPC。使用共享存储时要掌握的唯一窍门是多个进程之间对一给定存储区的同步访问,若服务器进程正在将数据放入共享存储区,则它做完这一操作之前,客户进程不应当去取这些数据。通常,信号量被用来实现对共享存储访问的同步。(记录锁也可用于这种场合)

*为了获得一个共享存储标识符,调用的第一个函数通常是shmget

int shmget(key_t key, size_t size, int flag)

*shmctl函数对共享存储段执行多种操作

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

*cmd参数指定下列5种命令中一种,使其在shmid指定的段上执行

IPC_STAT

IPC_SET

IPC_RMID 从系统中删除该共享存储段

SHM_LOCK 将共享存储段锁定在内存中

SHM_UNLOCK 解锁共享存储段

*一旦创建了一个共享存储段,进程就可调用shmat将其连接到它的地址空间中

void *shmat(int shmid, const void *addr, int flag)

共享存储段连接到调用进程的哪个地址上与addr参数以及在flag中是否制定SHM_RND位有关

(1)如果addr为0,则此段连接到由内核选择的第一个可用地址上

(2)如果addr非0,并且没有指定SHM_RND,则此段连接到addr所指定的地址上

(3)如果addr非0,并且指定了SHM_RND,则此段连接到(addr-(addr mod ulus SHMLBA))所表示的地址上。SHM_RND命令的意思是“取整”。SHMLBA的意思是“低边界地址倍数”,它总是2的乘方

*shmat的返回值是该段所连接的实际地址,如果出错则返回-1

*当对共享存储段的操作已经结束时,则调用shmdt脱接该段

int shmdt(void *addr)

*很多实现提供了一种类似于/dev/zero的设施,称为匿名存储映射

15.10 客户进程-服务器进程属性

*客户进程和服务器进程的某些属性受到它们之间所使用的IPC类型的影响。最简单的关系类型是使客户调用fork然后调用exec执行所希望的服务器进程。在fork之前先创建两个半双工管道使数据可在两个方向传输

APUE读书笔记-第15章-进程间通信的更多相关文章

  1. C++ primer plus读书笔记——第15章 友元、异常和其他

    第15章 友元.异常和其他 1. 友元类的所有方法都可以访问原有类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数.成员函数.或类为友元是由类定义的, ...

  2. APUE读书笔记-第17章-高级进程间通信

    17.1 引言 *两种高级IPC:基于STREAMS的管道(STREAMS-based pipe)以及UNIX域套接字(UNIX domain socket)可以在进程间传送打开文件描述符.服务进程可 ...

  3. 《Linux程序设计》--读书笔记---第十三章进程间通信:管道

    管道:进程可以通过它交换更有用的数据. 我们通常是把一个进程的输出通过管道连接到另一个进程的输入: 对shell命令来说,命令的连接是通过管道字符来完成的: cmd1    |     cmd2 sh ...

  4. 《python核心编程》读书笔记--第15章 正则表达式

    15.1引言与动机 处理文本和数据是一件大事.正则表达式(RE)为高级文本匹配模式,为搜索-替换等功能提供了基础.RE是由一些字符和特殊符号组成的字符串,它们描述了这些字符和字符串的某种重复方式,因此 ...

  5. APUE读书笔记-第13章-守护进程

    第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...

  6. APUE读书笔记-第18章-终端I/O

    18.1 引言 *终端I/O的用途很广泛,包括用于终端.计算机之间的直接连线.调制解调器以及打印机等等,所以终端I/O系统非常复杂 18.2 综述 *终端I/O有两种不同的工作模式: (1)规范模式输 ...

  7. APUE读书笔记-第14章-高级I/O

    14.1 引言 *高级I/O包括非阻塞I/O.记录锁.系统V流机制.I/O多路转换(select和poll函数).readv和writev函数以及存储映射I/O(mmap) 14.2 非阻塞I/O * ...

  8. INSPIRED启示录 读书笔记 - 第15章 特约用户

    产品开发伙伴 为了解决两个问题——既深入洞察目标用户的需求,又赢得用户对产品的推荐,建议征集特约用户协助完成产品研发 在项目的开始阶段物色至少六位积极.活跃.乐于分享的目标户,要求是他们在产品的目标用 ...

  9. 《LINUX内核设计与实现》第三周读书笔记——第一二章

    <Linux内核设计与实现>读书笔记--第一二章 20135301张忻 估算学习时间:共2小时 读书:1.5 代码:0 作业:0 博客:0.5 实际学习时间:共2.5小时 读书:2.0 代 ...

随机推荐

  1. phalcon Model 'partitions' could not be loaded(模型不支持分区语句)

    注意: 很明确提示用phalcon自带的模型层是不能用partition这个关键字的 解决方法: 自己写个PDO类 然后用pdo中的query方法执行语句成功: mysql分区目的 是减少数据库的负担 ...

  2. interfacer和abstarct class的异同

  3. Comparable<T> 和 Comparator<T>

    相同点: Comparable<T> 和 Comparator<T>都是接口 不同点: 两者声明的方法不同.前者是compareTo()方法,后者是compare()方法. C ...

  4. Shell中EOF内容转义

    1.在$符号前面加反斜杠,如: cat > test.sh <<EOF \$test EOF 如果不加,将转成实际的值. 2.给EOF加个双引号,如: cat > test.s ...

  5. 【scrapy】使用方法概要(一)(转)

    [请初学者作为参考,不建议高手看这个浪费时间] 工作中经常会有这种需求,需要抓取互联网上的数据.笔者就经常遇到这种需求,一般情况下会临时写个抓取程序,但是每次遇到这种需求的时候,都几乎要重头写,特别是 ...

  6. How to Run Syncthing 24/7 as a Windows Service with AlwaysUp

    http://www.coretechnologies.com/products/AlwaysUp/Apps/RunSyncthingAsAWindowsService.html Automatica ...

  7. 修改WampServer的默认端口

    WampServer默认的安装端口是80,容易和已安装的ISS等其他服务冲突,导致WampServer无法启动. 无法启动的现象如下: 1.apache服务无法启动.问题所在:80端口冲突. 2.在浏 ...

  8. 记录一次软件Bug发生的过程

    结束一周的紧张工作,难得的休息时光,坐在电脑前浏览博客.听听歌.看看大片,这也算是一种享受. 因为年度的开发任务已经开始了,所以最近会特别忙,新人的成长又没有想象中的好,经常在他们身上看到自己去年的影 ...

  9. 使用stream(流)实现多表数据传输

    使用stream(流)实现多表数据传输 几乎所有的TCP和HTTP通信控件都支持stream(流)的传输. 使用stream(流)是可以实现多表数据传输的. 但这需要自定义协议了: 合并后的strea ...

  10. error launching remote program failed to get the task for process

    Error  Starting executable: error launching remote program failed to get the task for process 715 这个 ...