-
第二卷 UNIX网络编程:进程间通信
资源介绍
本书全面深入地讲述了各种进程间通信(IPC)形式,它们是几乎所有复杂精致的UNIX程序的性能之关键。从网络编程角度看,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。本书从对Posix IPC和System V IPC的内部结构的综合讨论开始,具体阐述并比较了四种IPC形式:消息传递(管道、FIFO、消息队列)、同步(互斥锁、条件变量、读写锁、文件与记录锁、信号灯)、共享内存区(匿名共享内存区;有名共享内存区)及远程过程调用(Solaris门、Sun RPC)。在附录中给出了测量各种IPC形式之性能的方法。
本书内容详尽且具权威性,几乎每章都提供精选的习题,是计算机和网络专业高年级本科生和研究生的首选教材。本书也可作为网络研究和开发人员的自学教材和参考书。
本书全面深入地讲述了各种进程间通信(IPC)形式,它们是几乎所有复杂精致的UNIX程序的性能之关键。从网络编程角度看,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。本书从对Posix IPC和System V IPC的内部结构的综合讨论开始,具体阐述并比较了四种IPC形式:消息传递(管道、FIFO、消息队列)、同步(互斥锁、条件变量、读写锁、文件与记录锁、信号灯)、共享内存区(匿名共享内存区;有名共享内存区)及远程过程调用(Solaris门、Sun RPC)。在附录中给出了测量各种IPC形式之性能的方法。
本书内容详尽且具权威性,几乎每章都提供精选的习题,是计算机和网络专业高年级本科生和研究生的首选教材。本书也可作为网络研究和开发人员的自学教材和参考书。
目录
第1部分 简 介
第1章 简介
1.1 概述
1.2 进程、线程与信息共享
1.3 ipc对象的持续性
1.4 名字空间
1.5 fork、exec和exit对于ipc对象的影内
1.6 出错处理:包裹函数
1.7 unix标准
1.8 书中ipc例子索引表
1.9 小结
1.10 习题
第2章 posix ipc
2.1 概述
2.2 ipc名字
2.3 创建与打开ipc通道
2.4 ipc权限
2. 5 小结
2.6 习题
第3章 system v ipc
. 3.1 概述
3.2 key—t键和ftok函数
3.3 ipc—perm结构
3.4 创建与打开ipc通道
3.5 ipc权限
3.6 标识符重用
3.7 ipcs和ipcrm程序
3.8 内核限制
3.9 小结
3.10 习题
第2部分 消息传递
第4章 管道和fif0
4.1 概述
4.2 一个简单的客户—服务器例子
4.3 管道
4.4 全双工管道
4.5 popen和pclose函数
4.6 fifo
4.7 管道和fifo的额外属性
4.8 单个服务器,多个客户
4.9 迭代服务器与并发服务器
4.10 字节流与消息
4.11 管道和fif0限制
4.12 小结
4.13 习题
第5章 fosix消息队列
5.1 概述
5.2 mq—open、mq—close和mq—unlink函数
5.3 mq—getattr和mq—setattr函数
5.4 mq—send和mq—receive函数
5.5 消息队列限制
5.6 mq—notify函数
5.7 posix实时信号
5.8 使用内存映射i/o实现posix消息队列
5.9 小结
5.10 习题
第6章 system v消息队列
6.1 概述
6.2 msgget函数
6.3 msgsnd函数
6.4 msgrcv函数
6.5 msgctl函数
6.6 简单的程序
6.7 客户—服务器例子
6.8 复用消息
6.9 消息队列上使用select和po11
6.10 消息队列限制
6. 11 小结
6.12 习题
第3部分 同 步
第7章 互斥锁和条件变量
7.1 概述
7.2 互斥锁:上锁与解锁
7.3 生产者—消费者问题
7.4 上锁与等待
7.5 条件变量:等待与信号发送
7.6 条件变量:定时等待和广播
7.7 互斥锁和条件变量的属性
7.8 小结
7.9 习题
第8章 读写锁
8.1 概述
8.2 获取与释放读写锁
8.3 读写锁属性
8.4 使用互斥锁和条件变量实现读写锁
8.5 线程取消
8.6 小结
8.7 习题
第9章 记录上锁
9.1 概述
9.2 记录上锁与文件上锁
9.3 posix fcntl记录上锁
9.4 劝告性锁
9.5 强制性上锁
9.6 读出者和写入者的优先级
9.7 启动一个守护进程的唯一拷贝
9.8 文件作锁用
9.9 nfs上锁
9.10 小结
9.11 习题
第10章 possix信号灯
10.1 概述
10.2 sem—open、sem—close和sem—unlink函数
10.3 sem—wait和sem—trywait函数
10.4 sem—post和sem—getvalue函数
10.5 简单的程序
10.6 生产者—消费者问题
lo.7 文件上锁
10.8 sem—init和sem—destroy函数
10.9 多个生产者,单个消费者
10.10 多个生产者,多个消费者
10.11 多个缓冲区
10.12 进程间共享信号灯
10.13 信号灯限制
10.14 使用fifo实现信号灯
10.15 使用内存映射i/o实现信号
10.16 使用system v信号灯实现posix信号灯
10.17 小结
10.18 习题
第11章 system v信号灯
11.1 概述
11.2 semget函数
11.3 semop函数
11.4 semctl函数
11.5 简单的程序
11.6 文件上锁
11.7 信号灯限制
11.8 小结
11.9 习题
第4部分 共享内存区
第12章 共享内存区介绍
12.1 概述
12.2 mmap、munmap和msync函数
12.3 在内存映射文件中给计数器持续加1
12.4 4.4bsd匿名内存映射
12.5 svr4/dev/zero内存映射
12.6 访问内存映射的对象
12.7 小结
12.8 习题
第13章 posix共享内存区
13.1 概述
13.2 shm_open和shm_unlink函数
13.3 ftruncate和fstat函数
13.4 简单的程序
13.5 给一个共享的计数器持续加1
13.6 向一个服务器发送消息
13.7 小结
13.8 习题
第14章 system v共享内存区
14.1 概述
14.2 shmget函数
14.3 shmat函数
14.4 shmdt函数
14.5 shmctl函数
14.6 简单的程序
14.7 共享内存区限制
14.8 小结
14.9 习题
第5部分 远程过程调用
第15章 门
15.1 概述
15.2 door—call函数
15.3 door—create函数
15.4 door—return函数
15.5 door—cred函数
15.6 door—info函数
15.7 例子
15.8 描述字传递
15.9 door—sever—create函数
15.10 door—bind、door—unbind和door-revoke函数
15.11 客户或服务器的过早终止
15.12 小结
15.13 习题
第16章 sun rpc
16.1 概述
16.2 多线程化
16.3 服务器捆绑
16.4 认证
16.5 超时和重传
16.6 调用语义
16.7 客户或服务器的过早终止
16.8 xdr:外部数据表示
16.9 rpc分组格式
16.10 小结
16.11 习题
后 记
第6部分 附 录
附录a 性能测量
a.1 概述
a.2 结果
a.3 消息传递带宽程序
a.4 消息传递延迟程序
a.5 线程同步程序
a.6 进程同步程序
附录b 线程入门
b.1 概述
b.2 基本线程函数:创建和终止
附录c 杂凑的源代码
c.1 unpipc.h头文件
c.2 config. h头文件
c.3 标准错误处理函数
附录d 部分习题解答
附录e 参考文献
附录f 函数和宏定义索引表
附录g 结构定义索引表
附录h 中英文词汇对照表
↑折 叠
译者序
译者直到去年9月中旬才惊悉本书作者W.Richard Stevens博士已逝世的恶耗。在此之前译者只是奇怪有相当长的一段时间访问不了Stevens博士的个人主页,并没想到其背后隐蔽着这件令全世界计算机界和网络工作者为之扼腕叹息的事。当时本书的翻译工作尚未开始,译者也曾一度在是否接手翻译上徘徊,因为当时本人恰好有一个作为访问学者赴美工作的机会,然而自从参与翻译与审校本丛书第1卷以来,译者就深深地为Stevens博士的博学和极为严谨的治学风范所折服,由此产生了将整套丛书翻译成中文的使命感,第1卷中译本的广大读者以电子邮件方式向译者传递的赞誉、鼓励和希望尽早看到后续各卷中译本的心情也在敦促译者继续努力。Stevens博士与世长辞的消息最终令译者下定决心翻译出本卷——Stevens博士最后的著作。在让这部遗著的中译本尽快面世的内在动力推动下,经过近两个月夜以继日的工作,中译本初稿终于完成。
本书是《UNIx网络编程(第2版)》(UNIX Network Programming)这套计划中的三卷本丛书中第2卷的中译本。本丛书第l卷的副标题为“套接口API和x/open传输接口API”(Networking APIs:Sockets and XTI),讨论的是让连网的不同主机彼此交换信息的应用程序的编写细节。第2卷的副标题为“进程间通信”(Interprocess Communications),讨论的是同一主机内不同进程或线程彼此交换信息的应用程序的编写细节。按照Stevens博士原来的计划,第3卷的副标题为“应用程序”(Apphcations),它是对《UNIx网络编程(第1版)》(1990年)中第9至第18章内容的扩充,可想其内容之丰富。永远遗憾的是Stevens博士已不可能完成第3卷了,不过像Gary R.Wright等人也许能够把它整理并续写出来。Wright是Stevens博士另一套丛书即《TCP/IP阐述》(TCP/IP Illustrated)中第2卷的合作者,Stevens博士的个人主页也是他于去年10月初重新开通的。
本书作者Stevens博士的生平在《UNIX网络编程(第2版)》第1卷中译本的译者序中已经提到过。Stevens博士尽管时间非常宝贵,每天还要花不少时间阅读和回答读者们发给他的有关Unix和TCP/IP的电子邮件,因而颇受尊敬。Stevens博士本人也在与网友们的交往中获益不少,他在本书扉页上写的话就是:“献给Usenet社群;谢谢他们回答了许多问题,又提供了不少FAQ。”
与《UNIX网络编程(第2版)》第1卷的翻译一样,译者始终以教科书的要求认真对待本卷的翻译与审校工作。除根据作者给出的勘误表进行修正外,译者还就若干不易理解或易混淆的概念和说法给出了自己的见解和补充说明。本卷的翻译继承了第1卷中译本中的大多数说法,特别是其中以译者注形式强调的概念,本书不再重复说明。尽管如此,由于译者水平有限,译文中仍难免有不妥之处,敬请广大读者批评指正。就中译本中的技术问题,读者“可直接与译者本人联系,电子邮件地址为jzyang@chpcc.edu.cn,通信地址为清华大学网络中心。
译者最后特别感谢北京科海培训中心编辑室的全体同志,本书的出版与他们默默无闻的辛勤工作和热情的支持是分不开的。
译 者
2000年1月
前言
简介
多数精致复杂的程序涉及某种形式的IPC,也就是进程间通信(Interprocess Communication)。它是一个程序设计原则的自然结果,即把应用程序设计成一组彼此通信的小片段是比设计成单个庞大的程序更好的方法。从历史上看,应用程序设计方式按如下的顺序渐次出现:
1.完成全部工作的单个庞大的程序。整个程序的各种片段可作为函数实现,它们以函数参数、函数返回值及全局变量的形式彼此交换信息。
2.使用某种形式的IPC彼此通信的多个程序。许多标准Unix工具就是以这种样式设计的,它们使用shell管道(一种IPC形式)从一个程序向下一个程序传递信息。
3.由使用某种形式的IPC彼此通信的多个程序构成的单个程序。尽管这种通信发生在线程间而不是进程间,我们仍用IPC的说法来描述。
把后两种设计方式结合起来也是可能的:由多个进程组成,每个进程又由一个或多个线程构成,其中涉及给定进程内各线程间的通信以及不同进程间的通信。
到此为止所描述的是把完成一个给定应用所涉及的工作散布到多个进程中,也许还散布到进程内的线程中。在含有多个处理器(CPU)的系统上,多个进程可能(在不同的CPU上)同时运行,一个给定进程的多个线程也可能同时运行。因此,把一个应用的工作散布到多个进程或线程中有可能减少该应用完成给定任务的时间。
本书具体叙述4种不同形式的IPC:
1.消息传递(管道、FIFO、消息队列)
2.同步(互斥锁、条件变量、读写锁、文件与记录锁、信号灯)
3.共享内存区(匿名共享内存区、有名共享内存区)
4.远程过程调用(Solaris门、Sun RPC)
本书不讨论通过计算机网络通信的程序的编写。这种通信形式通常涉及使用TCP/IP协议族的所谓的套接口API(应用程序编程接口);这些主题在本丛书的第1卷[Stevens 1998]中详细讨论。
有人可能坚称单台主机内的即不涉及网络的IPC(正是本卷的主题)不应该使用,相反,所有应用程序都应该编写成通过网络运行在各种主机的分布式应用程序。然而实践证明,单台主机内的IPC与穿越网络的通信相比,前者往往快得多,有时还简单些。诸如共享内存区和同步这样的技术通常只在单台主机上可用,穿越网络时可能没法用。经验与历史告诉我们,不涉及网络的IPC(本卷)和穿越网络的IPC(本丛书第l卷)都有用武之地。
本书构筑在同一套丛书第1卷以及作者的其他4本书的基础之上,它们的书名在全书中缩写如下:
. UNPvl:UNIX Network Programming,Volume 1[Stevensl998]①
. APUE:Advanced Programming in the UNIX Environment[Stevensl992]
. TCPvl:TCP/IP Illustrated,Volume 1[Stevensl994]
. TCPv2:TCP/IP Illustrated,Volume 2[Wright and Stevensl995]
. TCPv3:TCP/IP Illustrated,Volume 3[Stevensl996]
. 尽管在以“网络编程”为书名的丛书中讨论IPC看起来可能奇怪,IPC却往往用在网络应用程序中。这正如在“UNIX Network Programming”1990年版的前言中所说:“理解如何给一个网络开发软件的必要条件之一是理解进程闻通信(1PC)”。
本书与第1版的差别
本卷是对“UNIX Network Programming”1990年版中第3章和第18章的完全重写和扩充。从词数上统计,整个材料扩充了5倍。下面是新版本中所做的主要修改:
·除了“System VIPC”的3种形式(消息队列、信号灯、共享内存区)外,还讨论了实现这3种形式IPC的更新的Posix函数。(我们将在1.7节谈一谈Posix标准族。)作者期待以后数年内PosixIPC函数有大的推广,它们与对等的System V函数相比毕竟有优势。
·讨论了Posix用于同步的函数:互斥锁、条件变量、读写锁。这些函数既可用于同步进程,也可用于同步线程,而且往往在访问共享内存区时使用。本卷假设有一个Posix线程环境(称为“Pthreads”),许多例子设计成使用多个线程而不是多个进程。
·关于管道、贝FO和记录上锁的讨论集中于它们的Posix定义。
·除讲述IPC机制并展示如何使用它们外,作者还开发了Posix消息队列、读写锁及Posix信号灯的实现(所有这些IPC机制都可作为用户函数库实现)。这些实现能够把许多不同的特性联结在一起(例如有一个Posix信号灯的实现同时用上了互斥锁、条件变量和内存映射I/O),并强调了在我们的应用程序中必须经常处理的条件 (例如竞争状态、出错处理、内存空间遗漏、可变长度参数表等)。理解某个特性的一种实现往往导致在如何使用该特性上取得更大的认识。
·关于RPC的讨论集中于Sun RPC软件包。在此之前我们将讲述新的S01ahs0门API,它与RPC类似,但限于单台主机。这么一来介绍了许多新特性,它们是调用另一个进程中的过程时需要关心的,不过网络连接的具体细节不必担心。
读者
本书既可作为关于IPC的指导书,也可作为有经验程序员的参考书。它分为4个部分:
·消息传递
·同步
·共享内存区
① 译者注:本书有中译本(清华大学出版社出版),在出现指向本书具体页码的参考点处,我们将注出中译本中的对应页码。
远程过程调用
不过许多读者可能只对其中的特定子集感兴趣。多数单章能彼此独立地分开阅读,但是第2章汇总了所有的PosixIPC函数共同的许多特性,第3章汇总了所有的System VIPC函数共同的许多特性,第12章则是对Posix和System V共享内存区的笼统介绍。所有读者都应阅读第1章,特别是1.6节,它们介绍了全书都用到的一些包裹函数。讨论PosixIPC的各章与讨论System VIPC的各章彼此独立,关于管道、FIFO和记录上锁的各章则不属于任何一个阵营。关于RPC的两章也不同于其他IPC技术。
为便于用作参考书,本书提供了全文索引,并在附录F和附录G中给出了所有的函数和结构的具体讲解所在的页码。为帮助那些以随意顺序阅读各主题的读者,全文提供了大量的对相关主题的参考点。
源代码和勘误表获取
本书中出现的所有例子的源代码都可从作者的主页获取,其URL地址列在本前言的末尾。学习本书中讲述的IPC技术的最好方法是使用这些程序,然后修改并改进它们。只有真正编写这种形式的代码,才能加深对概念的理解并提高编程技巧。各章最后提供了大量的习题,附录D给出了其中大多数的解答。
本书最新的勘误表也可从作者的主页获取 ②( ② 译者注:中译本已根据最后修改日期为1999年8月27的最新勘误表作过订正。)。
鸣谢
尽管作者的名字是唯一出现在封面上的,要创作一本高质量的教科书却免不了许多人的共同努力。首先应该而且最值得感谢的是作者的家庭成员,他们几乎天天承受着作者写书时的那些个漫长而难熬的钟点。再次谢谢你们,Sally、Bill、E11en、David。
作者感谢本书的技术性评阅人,他们提供了无价的反馈信息(打印出来共135页),帮助作者找出许多错误,指出需要进一步解释的地方,并提出另外的表述、用词和编码方案,他们是:Gavin Bowe、A11en Briggs、Dave Butenhof、Wan—Teh Chang、Chris C1eeland、Bob Friesenhahn、Andrew Giefth、Scott Johnson、Marty Leisner、Larry McVoy、Craig Metz、Bob Nelson、Steve Rago、Jim Reid、Swamy K.Sitarama、Jon C.Snader、Ian Lance Taylor、Rich Teer和Andy Tucker。
下面列出的网友回答了作者的电子邮件中的问题——有些网友还回答了不少,所有这些答复都有助于改进本书的精确性和语言表达,他们是:David Bausum、Dave Butenhof、Bill Gallmeister、Mukesh Kacker、Brian Kernighan、Larry McVoy、Steve Rago、Keith Skowran、Bart Smaalders、Andy Tucker和John Wait。
特别感谢GSquared的Larry Rafsky,原因很多。跟以往一样,作者感谢国家光学天文台(NOAO)、Sidney W01ff、Richard Wolff和Steve Grandi,他们允许作者访问他们的网络和主机。DEC公司的JimBound、Matt Thomas、Mary Clouter和Barb G1over提供的A1pha系统正是运行过本书中大多数例子的那台主机。本书中代码的一个子集是在其他Unix系统上测试的:作者感谢Red Hat软件公司的MichaelJohnson提供了Red Hat Linux的最新版本,IBM Austin的Dave Marquardt和Jessie Hang提供了一台RS/6000系统以及最新版本的AIX。
作者感谢Prentice Hall出版社那些勤勤恳恳的职员,谢谢他们的所有帮助,特别是在时间紧的情况下还能井然有序地把事情做好,他们是编辑Mary Franz以及编务Noreen Regina、Sophie Papanlko1aou和Patti Guerrieri。
附记
作者制作了本书的可照排拷贝(PostScript格式),这个拷贝随后排版成成品书。所用的格式化系统是James C1ark的优秀的groff软件包,它安装在运行So1aris 2.6的一台SparcStation工作站上。(宣判troff死刑的报告毫无疑问过度夸张了。)作者使用vi编辑器键人了总共138897个单词,使用gpic程序制作了72张插图(用到了Gary Wright编写的许多宏),使用gtbl程序生成了35个表格,执行了所有的索引任务(使用由John Bentley和Brian Kernighan编写的一组awk脚本),并完成了最终的页面布局。Dave Hanson的loom程序、GNU indent程序以及由Gary Wright编写的一些脚本程序用于把总共8046行C源代码插入到本书中。
- 上一篇: DS8700 磁盘总汇
- 下一篇: IBM V7000产品介绍