第五部分 远程过程调用
第15章 门
- CS架构的过程调用,三种不同类型
- 本地过程调用
- 单台主机上的远程过程调用(门)
- 在进程内部,门是用描述符标识的
- 在进程外,门可能是用文件系统中的路径名标识的
- 1.通过
door_create
创建一个门,参数是将与该门关联的过程的一个指针,返回值是新创建的门的一个描述符 - 2.通过
fattach
给这个门描述符关联一个路径名 - 3.一个客户通过调用
open
来打开一个门,参数是该门的服务器关联在其上的路径名,返回值是本客户访问该门的描述符- 权限测试
- 4.该客户通过调用
door_call
调用服务器过程- 可以同时从客户向服务器传递数据和描述符
- 反之亦然
- 5.服务器通过调用
door_return
返回 - 某个门的服务器可以是另一个门的客户
- 门调用是同步的
- 服务器过程必须是线程安全的
- 描述符传递允许一个进程把一个门传递给另外某个进程
- 调用fork之后,子进程与父进程共享所有打开着的描述符
- 调用exec之后,所有描述符通常仍保持打开
- 等势(idempotent),即幂等
- 用于描述一个过程时,意思是该过程可调用任意多次而不出问题
- 门具有本书其他IPC形式不具有的特性:可以确定客户的凭证
- 有效用户ID、实际用户ID
- 有效组ID、实际组ID
- 门过早终止
- EINTR错误
- 服务器线程通过接收一个线程取消请求得到通知
- 主机间的远程过程调用(RPC)
第16章 Sun RPC
- 程序结构
- 单一程序
- 彼此通信的多个进程
- 同一主机
- 不同主机
- 显式网络编程 explicit network programming
- socket
- 客户端:socket, connect, read, write
- 服务器:socket, bind, listen, accept, read, write
- socket
- 隐式网络编程 implicit network programming
- RPC
- 调用和被调用涉及网络IO,但是对程序员是透明的
- 端口映射器 RPCBIND
- 认证
- 空认证(null authentication)或AUTH_NONE
- Unix认证(Unix authentication)
- 主机名、有效用户ID、有效组ID、多个辅助组ID
- 超时和重传策略
- 超时
- 总超时 total timeout
- 重试超时 retry timeout,只用于UDP
- 超时
- TCP连接管理
- 事务ID(transaction ID) XID
- 服务器重复请求高速缓存
- 调用语义
- 分成三类
- 正好一次(exactly once)
- 最多一次(at most once):如果出错返回,不能肯定是否已执行
- 最少一次(at least once)
- 三种情形
- TCP协议
- UDP,带有服务器高速缓存
- UDP,没有任何服务器高速缓存
- 分成三类
- RPC请求格式
- IP首部
- TCP首部
- 标志+长度
- 事务ID
- 消息类型
- RPC版本
- 程序号
- 版本号
- 过程号
- 认证形式
- 凭证长度
- 凭证数据
- 认证形式
- 验证器长度
- 验证器数据
- 过程参数
- TCP是字节流,不提供消息边界,应用程序必须提供界定各个消息的某种方法
- 记录(record)
- 由一个或多个片段(fragment)构成
- 片段
- 4字节头
- 最高位是最终片段标志
- 低序31位是计数
- 4字节头
- 记录(record)
- RPC应答格式(UDP)
- IP首部
- UDP首部
- 事务ID
- 消息类型
- 应答状态
- 认证形式
- 验证器长度
- 验证器数据
- 接受状态
- 过程结果
- RPC
- 显式网络编程 explicit network programming
后记
- 使用情境
- 消息队列和过程调用往往单独使用(他们通常提供了自己的同步机制)
- 共享内存区需要提供某种同步
- 同步有时候单独使用
- 要考虑的四个前提
- 是否联网(networked or nonnetworked)
- 可移植性(portability)
- 性能(performance)
- 实时调度(realtime scheduling)
附录A 性能测量
- 带宽(bandwidth)
- 延迟(latency)
附录B 线程入门
- fork开销很大,尽管使用了COW
- 子进程向父进程返回信息颇费周折?
- 一个进程内的所有线程共享同一个全局内存空间
- 同时带来了同步问题
- 共享的内容
- 全局变量
- 进程指令
- 大多数数据
- 打开的文件
- 信号处理程序和信号处置
- 当前工作目录
- 用户ID和组ID
- 线程间独特的内容
- 线程ID
- 寄存器集合(包括程序计数器和栈指针)
- 栈(用于存放局部变量和返回地址)
- errno
- 信号掩码
- 优先级