商家名称 | 信用等级 | 购买信息 | 订购本书 |
UNIX网络编程.卷2:进程间通信(第2版)(图灵计算机科学丛书 ) | |||
UNIX网络编程.卷2:进程间通信(第2版)(图灵计算机科学丛书 ) |
《UNIX网络编程.卷2:进程间通信(第2版)》:图灵计算机科学丛书
作者:(美国)W.Richard Stevens
W.Richard Stevens,国际知名的UNIX和网络专家,备受赞誉的技术作家他1951年2月5日出生于赞比亚,后随父母回到美国中学时就读于弗吉尼亚菲什伯恩军事学校,1973年获得密歇根大学航空和航天工程学士学位,1975年至1982年,他在亚利桑那州图森市的基特峰国家天文台从事计算机编程工作,业余时间喜爱飞行运动,做过兼职飞行教练这期间他分别在1978年和1982年获得亚利桑那大学系统工程硕士和博士学位此后他去康涅狄格州纽黑文的健康系统国际公司任主管计算机服务的副总裁,1990年他回到图森,从事专业技术写作和咨询工作写下了多种经典的传世之作。
第一部分 简介
第1章 简介 2
1.1 概述 2
1.2 进程、线程与信息共享 3
1.3 IPC对象的持续性 4
1.4 名字空间 5
1.5 fork、exec和exit对IPC对象的影响 7
1.6 出错处理:包裹函数 8
1.7 Unix标准 9
1.8 书中IPC例子索引表 11
1.9 小结 13
习题 13
第2章 Posix IPC 14
2.1 概述 14
2.2 IPC名字 14
2.3 创建与打开IPC通道 16
2.4 IPC权限 18
2.5 小结 19
习题 19
第3章 System V IPC 20
3.1 概述 20
3.2 key_t键和ftok函数 20
3.3 ipc_perm结构 22
3.4 创建与打开IPC通道 22
3.5 IPC权限 24
3.6 标识符重用 25
3.7 ipcs和ipcrm程序 27
3.8 内核限制 27
3.9 小结 28
习题 29
第二部分 消息传递
第4章 管道和FIFO 32
4.1 概述 32
4.2 一个简单的客户-服务器例子 32
4.3 管道 32
4.4 全双工管道 37
4.5 popen和pclose函数 39
4.6 FIFO 40
4.7 管道和FIFO的额外属性 44
4.8 单个服务器,多个客户 46
4.9 对比迭代服务器与并发服务器 50
4.10 字节流与消息 51
4.11 管道和FIFO限制 55
4.12 小结 56
习题 57
第5章 Posix消息队列 58
5.1 概述 58
5.2 mq_open、mq_close和mq_unlink函数 59
5.3 mq_getattr和mq_setattr函数 61
5.4 mq_send和mq_receive函数 64
5.5 消息队列限制 67
5.6 mq_notify函数 68
5.7 Posix实时信号 78
5.8 使用内存映射I/O实现Posix消息队列 85
5.9 小结 101
习题 101
第6章 System V消息队列 103
6.1 概述 103
6.2 msgget函数 104
6.3 msgsnd函数 104
6.4 msgrcv函数 105
6.5 msgctl函数 106
6.6 简单的程序 107
6.7 客户-服务器例子 112
6.8 复用消息 113
6.9 消息队列上使用select和poll 121
6.10 消息队列限制 122
6.11 小结 124
习题 124
第三部分 同步
第7章 互斥锁和条件变量 126
7.1 概述 126
7.2 互斥锁:上锁与解锁 126
7.3 生产者-消费者问题 127
7.4 对比上锁与等待 131
7.5 条件变量:等待与信号发送 132
7.6 条件变量:定时等待和广播 136
7.7 互斥锁和条件变量的属性 136
7.8 小结 139
习题 139
第8章 读写锁 140
8.1 概述 140
8.2 获取与释放读写锁 140
8.3 读写锁属性 141
8.4 使用互斥锁和条件变量实现读写锁 142
8.5 线程取消 148
8.6 小结 153
习题 153
第9章 记录上锁 154
9.1 概述 154
9.2 对比记录上锁与文件上锁 157
9.3 Posix fcntl记录上锁 158
9.4 劝告性上锁 162
9.5 强制性上锁 164
9.6 读出者和写入者的优先级 166
9.7 启动一个守护进程的唯一副本 170
9.8 文件作锁用 171
9.9 NFS上锁 173
9.10 小结 173
习题 174
第10章 Posix信号量 175
10.1 概述 175
10.2 sem_open、sem_close和sem_unlink函数 179
10.3 sem_wait和sem_trywait函数 180
10.4 sem_post和sem_getvalue函数 180
10.5 简单的程序 181
10.6 生产者-消费者问题 186
10.7 文件上锁 190
10.8 sem_init和sem_destroy函数 191
10.9 多个生产者,单个消费者 193
10.10 多个生产者,多个消费者 196
10.11 多个缓冲区 199
10.12 进程间共享信号量 205
10.13 信号量限制 206
10.14 使用FIFO实现信号量 206
10.15 使用内存映射I/O实现信号量 210
10.16 使用System V信号量实现Posix信号量 218
10.17 小结 224
习题 225
第11章 System V信号量 226
11.1 概述 226
11.2 semget函数 227
11.3 semop函数 229
11.4 semctl函数 231
11.5 简单的程序 232
11.6 文件上锁 237
11.7 信号量限制 238
11.8 小结 242
习题 242
第四部分 共享内存区
第12章 共享内存区介绍 244
12.1 概述 244
12.2 mmap、munmap和msync函数 247
12.3 在内存映射文件中给计数器持续加1 250
12.4 4.4BSD匿名内存映射 254
12.5 SVR4/dev/zero内存映射 255
12.6 访问内存映射的对象 255
12.7 小结 259
习题 260
第13章 Posix共享内存区 261
13.1 概述 261
13.2 shm_open和shm_unlink函数 261
13.3 ftruncate和fstat函数 262
13.4 简单的程序 263
13.5 给一个共享的计数器持续加1 267
13.6 向一个服务器发送消息 270
13.7 小结 275
习题 275
第14章 System V共享内存区 276
14.1 概述 276
14.2 shmget函数 276
14.3 shmat函数 277
14.4 shmdt函数 277
14.5 shmctl函数 277
14.6 简单的程序 278
14.7 共享内存区限制 281
14.8 小结 282
习题 283
第五部分 远程过程调用
第15章 门 286
15.1 概述 286
15.2 door_call函数 291
15.3 door_create函数 292
15.4 door_return函数 293
15.5 door_cred函数 294
15.6 door_info函数 294
15.7 例子 295
15.8 描述符传递 306
15.9 door_sever_create函数 310
15.10 door_bind、door_unbind和door_revoke函数 315
15.11 客户或服务器的过早终止 315
15.12 小结 321
习题 322
第16章 Sun RPC 323
16.1 概述 323
16.2 多线程化 330
16.3 服务器捆绑 333
16.4 认证 336
16.5 超时和重传 338
16.6 调用语义 342
16.7 客户或服务器的过早终止 343
16.8 XDR:外部数据表示 345
16.9 RPC分组格式 361
16.10 小结 365
习题 366
后记 368
附录A 性能测量 371
附录B 线程入门 406
附录C 杂凑的源代码 409
附录D 精选习题解答 417
参考文献 433
索引 435
大多数重要的程序都涉及进程间通信(Inter process Communication,IPC)。这是受下述设计原则影响的自然结果:把应用程序设计为一组相互通信的小片断比将其设计为单个庞大的程序更好。从历史角度看,应用程序有如下几种构建方法。
(1)用一个庞大的程序完成全部工作。程序的各部分可以实现为函数,函数之间通过参数、返回值和全局变量来交换信息。
(2)使用多个程序,程序之间用某种形式的IPC进行通信。许多标准的Unix工具都是按这种风格设计的,它们使用shell管道(IPC的一种形式)在程序之间传递信息。
(3)使用一个包含多个线程的程序,线程之间使用某种IPC。这里仍然使用术语IPC,尽管通信是在线程之间而不是在进程之间进行的。
还可以把后两种设计形式结合起来:用多个进程来实现,其中每个进程包含几个线程。在这种情况下,进程内部的线程之间可以通信,不同的进程之间也可以通信。
上面讲述了可以把完成给定任务所需的工作分到多个进程中,或许还可以进一步分到进程内的多个线程中。在包含多个处理器(CPU)的系统中,多个进程也许可以(在不同的CPU上)同时运行,或许给定进程内的多个线程也能同时运行。因此,把任务分到多个进程或线程中有望减少完成指定任务的时间。
本书详细讲述了用于进程间通信(IPC)的四种不同技术:
(1)消息传递(管道、FIFO、Posix莉lSystemV消息队列);
(2)同步(互斥锁、条件变量、读写锁、文件和记录锁、.Posix和SystemV信号量);
(3)共享内存区(匿名共享内存区、有名Posix共享内存区、有名SystemV共享内存区);
(4)过程调用(Solaris门、SunRPC)。
消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制。相反,共享内存区通常需要某种由应用程序提供的同步形式才能正确工作.同步技术有时候单独使用,也就是说不涉及其他形式的IPC。
讨论了共16章的细节后,很显然的一个问题是:解决某个特定问题应使用哪种形式的IPC?遗憾的是不存在关于IPC的简单判定。Unix提供的类型如此之多的IPC表明,不存在解决全部(或者甚至于大部分)问题的单一办法。你能做的仅仅是:逐渐熟悉各种IPC形式提供的机制,然后根据特定应用的要求比较它们的特性。
我们首先列出必须考虑的四个前提,因为它们对于你的应用程序相当重要。
(1)连网的(networked)还是非连网的(nonnetworked)。我们假设已作出这个决定,IPC就是用于单台主机上的进程或线程间的。如果应用程序有可能散布到多台主机上,那就考虑使用套接字代替IPC,从而简化以后向连网的应用程序转移的工作。
插图:
即使一个进程终止时系统会自动释放某个锁,那也可能解决不了问题。该锁保护某个临界区很可能是为了在执行该临界区代码期间更新某个数据。如果该进程在执行该临界区的中途终止,该数据处于什么状态呢?该数据处于不一致状态的可能性很大:举例来说,一个新条目也许只是部分插入某个链表中,要是该进程终止时内核仅仅把那个锁解开的话,使用该链表的下一个进程就可能发现它已损坏。
然而在某些例子中,让内核在进程终止时清理某个锁(若是信号量情况则为计数器)不成问题。例如,某个服务器可能使用一个SystemV信号量(打开其SEM-UNDO特性)来统计当前被处理的客户数。每次fork一个子进程时,它就把该信号量加1,当该子进程终止时,它再把该信号量减1。如果该子进程非正常终止,内核仍会把该计数器减1。9.7节给出了一个例子,说明内核在什么时候释放一个锁(不是我们刚讲的计数器)合适。那儿的守护进程一开始就在自己的某个数据文件上获得一个写入锁,然后在其运行期间一直持有该锁。如果有人试图启动该守护进程的另一个副本,那么新的副本将因为无法取得该写入锁而终止,从而确保该守护进程只有一个副本在一直运行。但是如果该守护进程不正常地终止了,那么内核会释放该写入锁,从而允许启动该守护进程的另一个副本。
相关阅读:
更多图书资讯可访问读书人图书频道:http://www.reAder8.cn/book/