四,进程间通信
1. 管道 (pipe) 的限制
UNIX 管道要求所有的通信进程都源自一个共同的父进程。因此,管道的使用造成了一些系统在设计上采用了有些不自然的结构。
2.naive/sophisticated process
所谓一个单纯进程 (navie process) 就是仅靠从标准输入文件中读数据和向标准输出文件写数据来完成工作的进程。
而一个成熟的进程 (sophisticated process) 则了解和掌握了操作系统提供的更多接口,并且它能用掌握的这些信息完成自己的工作。
3.IPC 在设计上应支持的特性
透明性: IPC 应该和这些通信进程是否在同一台机器上没有关系。
高效性
兼容性:现有的单纯进程应该无需改动便可以在分布式环境里使用。
4. 通信语义与属性
通信的语义包括:可靠数据传输的代价 (cost), 支持组播 (multicast) 传输,以及能够传送访问权限或能力等等。
其属性有:
-
数据的有序传送
-
数据的无重复发送
-
数据的可靠传送
-
面向连接的通信
-
信息分界的保存
-
对带外消息的支持
带外 (out-of-band) 消息是在正常传入流 ( 即带内数据 ) 之外发送给接收方的消息。通常是在紧急或异常情况下发送它。
5. 常用套接口
1> 数据报套接口 (datagram socket) 提供了一个不可靠的,无连接数据包通信模型;
2> 流套接口 (stream socket) 提供了一个可靠的,面向连接的字节流模型,支持带外数据发送;
3> 有序数据包套接口 (sequenced packet socket) 提供了一个有序,可靠,无重复的机遇连接的通信模型。
连接是一种由协议使用的机制,协议用它来避免在每个发送的数据包上都带套接口标识。两端都各自保留状态信息。另一方面,无连接的同学要求在每一次传送时都带上源和目的地址。
6. 使用套接口
( UNP 才是关于 socket 的最佳参考资料)
创建套接口
int sock, domain = AF_INET, type = SOCK_STREAM, protocol = 0;
sock = socket(domain, type, protocol);
初始化一个连接
int error;
int sock; /* Previously created by a socket() call. */
struct sockaddr_in rmtaddr; /* Assigned by the program. */
int rmtaddrlen = sizeof (struct sockaddr_in);
error =
connect(sock, (struct sockaddr *)&rmtaddr, rmtaddrlen);
客户端就到吃为止了,而服务器端则需把一个地址同一个套接口绑定
int error;
int sock;
struct sockaddr_in addr;
int addrlen = sizeof (struct sockaddr_in);
error =
bind(sock, (struct sockaddr*)&localaddr, localaddrlen);
监听套接口
int error, sock, backlog;
error = listen(sock, backlog);
接受传入的连接
int newsock, sock;
struct sockaddr_in clientaddr;
int clientaddrlen = sizeof(struct sockaddr_in);
newsock =
accept(sock, (struct sockaddr *)&clientaddr, clientaddrlen);
在套接口上发送和接受数据的例程
Routine
|
Connected
|
Disconnected
|
Address Info
|
read
|
Y
|
N
|
N
|
readv
|
Y
|
N
|
N
|
write
|
Y
|
N
|
N
|
writev
|
Y
|
N
|
N
|
recv
|
Y
|
Y
|
N
|
send
|
Y
|
Y
|
N
|
recvmsg
|
Y
|
Y
|
Y
|
sendmsg
|
Y
|
Y
|
Y
|
Sendmsg 与 recvmsg 还可以传递有特殊解释的辅助数据或者控制信息

IPC 覆盖在连网机制上,应用程序的数据流通过套接口层到达网络层,反之亦然。套接口层所需的状态完全封装在它自己的里面,而所有与协议有关的状态都保存在专门支持该协议的辅助数据结构中。而存储传输数据的责任则从套接口层下放到网络层。始终坚持这原则有助于简化存储管理的细节。

套接口层支持的例程
Routine
|
Function
|
socreate()
|
create a new socket
|
sobind()
|
bind a name to a socket
|
solisten()
|
mark a socket as listening for connection requests
|
soclose()
|
close a socket
|
soabort()
|
abort connection on a socket
|
soaccept()
|
accept a pending connection on a socket
|
soconnect()
|
initiate a connection to another socket
|
soconnect2()
|
create a connection between two sockets
|
sodisconnect()
|
initiate a disconnect on a connected socket
|
sosend()
|
send data
|
soreceive()
|
receive data
|
soshutdown()
|
shut down data transmission or reception
|
sosetopt()
|
set the value of a socket option
|
sogetopt()
|
get the value of a socket option
|
7. IPC 和网络协议对内存管理模式的要求
-
需要内存的可能是想通信协议数据包这样长度不定的结构。
-
数据包和其他数据对象必须在等待发送和接受时排成队列。
8.mbuf
mbuf 即内存缓冲区 (memory buffer) ,它的大小随着它所保存的内容不同而变化。所有的 mbuf 都包含一个大小固定的 m_hdr 结构,这个结构记录了各种有关 mbuf 的信息位。一个只含数据的 mbuf 有 234 字节的空间 (mbuf 总长 256 字节,减去 mbuf 头 [m_hdr] 的 22 字节 ) 。

把一则消息的内容向上传递给更高层的处理模块之前,协议要例行地剥去此消息前后的协议信息;而在向下传递消息时,又要加上协议信息。
由 m_next 链接器阿里的一个 mbuf 结构的集合称为一个链;而由 m_nextpkt 链接起来的若干个 mbuf 链则被称为一个队列。
mbuf 除了 m_hdr 外还可以只用标志指定第二组数据包头

Memory-buffer (mbuf) data structure with M_PKTHDR

Memory-buffer (mbuf) data structure with external storage
9.mbuf 的数据域长度固定不可变的原因
-
长度固定使得内存的碎片化降至最低
-
要求通信协议频繁地在已有的数据区前后添加协议头,对数据区进行分割,或者是从一个数据区的开始或末尾截取数据。 Mbuf 在设计必须能够在热和可能的时候无需重新分配或复制内存,就可以处理这样的变化。
-
如果 mbuf 打大小不固定的话,一些相关函数的执行开销将会大得多。
10. 为了支持 SMP 对 mbuf 的改进
每个 CPU 都有自己的存放 mbuf 和 mbuf 簇的链表。还有一个通用的 mbuf 和 mbuf 簇的链表,当每个 CPU 自己的链表使用完了,就要尝试从那个通用链表分配内存,而当每个 CPU 自己的链表都有足够空间了,就要把内存释放回该通用链表。
11.socket 与通信域的相关数据结构
1> 系统支持的套接口类型
Name
|
Type
|
Properties
|
SOCK_STREAM
|
stream
|
reliable, sequenced, data transfer; may support out-of-band data
|
SOCK_DGRAM
|
datagram
|
unreliable, unsequenced, data transfer, with message boundaries preserved
|
SOCK_SEQPACKET
|
sequenced packet
|
reliable, sequenced, data transfer, with message boundaries preserved
|
SOCK_RAW
|
raw
|
direct access to the underlying communication protocols
|
2>domain 结构

其中 dom_family 项去确定了通信域所使用的地址族
Name
|
Description
|
AF_LOCAL
|
(AF_UNIX) local communication
|
AF_INET
|
Internet (TCP/IP)
|
AF_INET6
|
Internet Version 6 (TCP/IPv6)
|
AF_NS
|
Xerox Network System (XNS) architecture
|
AF_ISO
|
OSI network protocols
|
AF_CCITT
|
CCITT protocols, e.g., X.25
|
AF_SNA
|
IBM System Network Architecture (SNA)
|
AF_DLI
|
direct link interface
|
AF_LAT
|
local-area-network terminal interface
|
AF_APPLETALK
|
AppleTalk network
|
AF_ROUTE
|
communication with kernel routing layer
|
AF_LINK
|
raw link-layer access
|
AF_IPX
|
Novell Internet protocol
|
3>socket 结构

Socket 包含的信息有关它们的类型,使用的支持协议以及它们的状态。
State
|
Description
|
SS_NOFDREF
|
no file-table reference
|
SS_ISCONNECTED
|
connected to a peer
|
SS_ISCONNECTING
|
in process of connecting to peer
|
SS_ISDISCONNECTING
|
in process of disconnecting from peer
|
SS_CANTSENDMORE
|
cannot send more data to peer
|
SS_CANTRCVMORE
|
cannot receive more data from peer
|
SS_RCVATMARK
|
at out-of-band mark on input
|
SS_ISCONFIRMING
|
peer awaiting connection confirmation
|
SS_NBIO
|
nonblocking I/O
|
SS_ASYNC
|
asynchronous I/O notification
|
SS_INCOMP
|
connection is incomplete and not yet accepted
|
SS_COMP
|
connection is complete but not yet accepted
|
SS_ISDISCONNECTED
|
socket is disconnected from peer
|
用来接受传入连接请求的套接口有两个与连接请求相关的套接口队列。由 so_incomp 字段开头的套接口链表代表了一个由连接组成的队列,必须在协议层完成这些连接后才能将它们返回。 so_comp 字段开头的则是一个准备返回给监听进程的套接口链表。
4> 套接口地址


12. 高位线、低位线
为了避免耗尽资源,对于在一个套接口数据缓冲区中排队的数据字节数,也就是数据所能使用的存储空间量,套接口都给它们设置了上界。这个高位线 (high watermark) 由协议进行初始化,当然一个应用程序也可以改变这个值,但它不能超过系统最大值 ( 通常是 256KB) 。网络协议能够检查高位线,并将这个值用于流控策略。在每个套接口数据缓冲区中还有一个低位线 (low watermark) 。低位线是满足一次数据接收请求所需要的最少字节数,应用程序可以通过它控制数据流。
13. 建立连接
进程对接期间套接口的状态转换图

Socket state transitions during process rendezvous
在套接口上排队以等待 accept() 调用的链接

在连接建立的过程中,套接口的状态有套接口层和支持协议层联合管理。一个协议永远不会直接改变套接口的状态值;为促进模块化,所有的改变都由替代套接口例程来执行。这些例程按照指示改变套接口的状态,并通知任何处于等待中的进程。支持协议层从来不直接使用同步或信号机制。异步检查出的错误被传递到一个套接口的 so_error 项中。
14. 传送 / 接收数据
套接口层主要的工作就是发送和接收数据。必须注意,除了可以选择加记录边界之外,套接口层本身明确不允许在通过套接口传输或接收的数据上施加任何结构。在整个 IPC 中,对任何数据的解释或者结构化在逻辑上都独立于通信域的实现。
对于那些要保证数据可靠传递的套接口来说,协议通常要在套接口的发送队列里保留所有要发送数据的一个副本,直到接收方确认收到这些数据为止。那些不保证数据一定发送到的协议则通常从 sosend 中接受数据,然后将其直接发往目的地,不保存任何副本。但是 sosend() 自己并不区分可靠与不可靠传输。
在接受数据缓冲中出现的数据组织通常有 3 中情况:分别针对流,数据报以及有序数据包的套接口。在一般情况下,接收数据缓冲区是按照消息链表的方式来组织的。

Data queueing for datagram socket
15. 关闭套接口
1> 对可靠协议的 close 隐含的语义
当一个承诺可靠传送数据的套接口在关闭时还有排队等待发送的数据,或者还有等待确认收到的数据,套接口就必须为了 close 调用, ( 可能无限次地 ) 尝试发送这些数据,以保证套接口承诺的可靠传递数据的语义。如果套接口为了使 close 调用成功完成而丢弃数据的话,它就违背了关于可靠传递数据的承诺。根据 close 隐含语义,丢弃数据就可能导致这些进程在网络环境中的工作不可靠。然而,如果一直到所有的数据都被成功发送后才关闭套接口,那么,在有些通信域中, close 调用可能永远不会结束。
2> 关闭套接口时其状态转换图

16. 本地 IPC
本地 IPC 的用户级 API
Subsystem
|
Create
|
Control
|
Communicate
|
semaphores
|
semget
|
semctl
|
semop
|
message queues
|
msgget
|
mesgctl
|
msgrcv, msgsnd
|
shared memory
|
shmget
|
shmctl, shmdt
|
n/a
|
消息队列天生就是半双工的,在通信端点之间传递的消息里带有一个类型和一个数据区。

对于共享内存,当进程用完共享内存的时候,它就使用系统调用 shmdt 把共享内存从它的进程空间中剥离。这个例程不会释放共享内存,因为其他进程可能还在使用它,但是它会解除调用它的进程对虚拟内存的映射。
分享到:
- 2009-05-22 16:37
- 浏览 1596
- 评论(0)
- 论坛回复 / 浏览 (0 / 2508)
- 查看更多
相关推荐
初级Freebsd命令学习和使用方法让菜鸟们更加了解Freebsd命令.
### FreeBSD学习笔记整理 #### 一、系统基本信息查询 **1. 查看CPU信息** - 使用`sysctl hw.model hw.ncpu`命令可以查看到CPU的型号和核心数量。 - `dmesg | grep "CPU:"`命令也可以用来获取CPU的相关信息。 **2...
标题与描述均提到了“freebSD学习手册”,这表明文档是关于学习FreeBSD操作系统的指南。FreeBSD是一种类Unix操作系统,它以其稳定性、安全性和性能而闻名,被广泛应用于服务器、嵌入式系统和高性能计算环境。学习...
《FreeBSD完全学习》一书提供了详尽的指南,涵盖了FreeBSD操作系统的各个方面,包括安装、配置、开发等,旨在帮助读者全面掌握FreeBSD的使用与管理。以下是从标题、描述、标签及部分内容中提取的关键知识点: ### 1...
freebsd学习资料大全连载,包括安装配置
虽然这个压缩包的标题中提到了`linux`,但请注意,FreeBSD和Linux在内核设计上有许多不同之处。Linux采用微内核架构,而FreeBSD采用单内核设计。此外,它们的许可证也不同,Linux遵循GPL,而FreeBSD遵循BSD许可证。...
压缩文件里包含了:FreeBSD技术内幕.pdf,FreeBSD命令.doc,FreeBSD使用手册.pdf,FreeBSD系统结构手册.pdf,FreeBSD-Porter手册.pdf,解压文件\FreeBSD开发手册.url
根据提供的信息,我们可以总结并详细解释FreeBSD学习手册中的关键知识点。这本手册涵盖了FreeBSD的安装、配置等各个方面,是学习FreeBSD操作系统的重要资源。 ### 标题:FREEBSD学习手册 #### 解释: 标题明确指出...
教程名称:FreeBSD网络操作系统视频教程课程目录:【】Apachel服务器系列之一(楚...FreeBSD讲义之内核编绎(楚广明之四)【】FTP系列服务器设置之一(楚广明 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
FreeBSD 8.4是FreeBSD操作系统的一个稳定版本,它基于FreeBSD的开源Unix-like系统,以其稳定性、安全性和灵活性而著称。本指南将详细阐述FreeBSD 8.4的安装过程,以及如何在安装完成后部署Panabit网络管理软件。 一...
freeBSD中文学习手册,是学习freeBSD的不错选择
- 描述了FreeBSD如何创建、调度和管理进程,包括并发执行、信号、进程间通信(IPC)等。 - 进程控制命令如`ps`, `kill`, `nice`在手册中会有详尽解释。 4. **文件系统** - FreeBSD采用Berkeley Fast File System...
FreeBSD上的Rsync同步学习与配置是一个重要的话题,特别是对于那些需要高效、可靠地备份和同步数据的系统管理员而言。Rsync是一款强大的文件同步工具,最初设计用来替代rcp,由rsync.samba.org维护。它以其独特的...
根据提供的信息,我们可以总结并详细解释FreeBSD中文使用手册中的关键知识点。 ### 1. FreeBSD 文档项目(The FreeBSD Documentation Project) FreeBSD文档项目是一个旨在为FreeBSD用户提供全面、准确的技术文档...
- **项目背景**:FreeBSD开发手册是The FreeBSD Documentation Project的核心成果之一,旨在为开发者和用户提供全面且深入的技术指南,帮助他们更好地理解FreeBSD系统的工作原理,并掌握系统的开发、配置与管理技巧...
综上所述,FreeBSD系统编程涉及多个层次的技术和概念,从底层硬件到高层应用,从单机到网络,都需要系统地学习和实践。通过阅读《FreeBSD系统编程》这样的资源,开发者可以逐步掌握这一领域的核心技能。
FreeBSD 是一个开源的类Unix操作系统,源自Berkeley Software Distribution(BSD)系统。这份"FreeBSD中文手册"是针对FreeBSD系统用户和管理员的一份详细参考资料,旨在帮助读者理解和掌握FreeBSD的操作、安装和日常...
通过阅读这本书,读者不仅可以学习到FreeBSD的设计理念,还能掌握如何在实际项目中应用这些知识,提高系统开发和维护的效率。FreeBSD作为一个开源项目,它的成功充分展示了开源文化的强大力量,也为操作系统的研究和...
- **与其它系统的比较**:如与Linux的对比,帮助读者更好地理解FreeBSD的独特之处。 #### 二、FreeBSD文档与社区支持 **知识点概述:** - **在线文档**:包括在线手册、GNU info等,这些资源对于学习FreeBSD至关...