本地过程调用

本地过程调用LPCLocal Procedure Call,通常也被称为轻量过程调用或者本地进程间通信) 是一种由Windows NT内核提供的内部进程间通信方式。通过这一方式,同一计算机上的进程可以进行轻量的通信。在Windows Vista中,ALPCAdvanced Local Procedure Call,高级本地进程通信)替代了LPC。ALPC提供了一个高速可度量的通信机制,这样便于实现需要在用户模式下高速通信的用户模式驱动程序框架(UMDF,User-Mode Driver Framework)。

本地过程调用接口是Windows NT未公开原生API的一部分。这样的API不能够直接使用,但是可以通过如下方式间接使用:

  • 使用Microsoft 遠程過程調用 API进行本地通信,例如,在同一计算机上实现不同处理器之间的通信
  • 调用Windows API中由LPC实现的部分(如下)。

实现

LPC由内核的“端口”对象实现,这样可以确保安全(由访问控制表规定持有特定的安全标识符才可以访问)并可以验证链接另一端进程的身份。程序也可以对每一个信息设定安全标识符,并测试对应信息的变化,以实现每一条消息的安全性。

服务端和客户端之间典型的连接由下列过程表示:

  1. 服务端进程建立命名服务器连接端口对象,并等待客户端连接;
  2. 客户端通过向这一端口发送消息来建立连接;
  3. 如果服务端同意建立连接,便会建立两个无名端口
    • 客户端连接端口:客户线程由此向服务端发送数据;
    • 服务端连接端口:服务端由此向客户端发送数据;每个客户端都分配一个独立的接口;
  4. 服务端持有一个服务连接端口的句柄,同时客户端也持有一个客户连接端口的句柄,这样进程间通信的通道就建立了。

本地过程调用支持以下三种交换信息的方式:

  • 针对较短信息(小于256字节):系统内核在进程间直接复制消息,从发送方的地址空间拷贝消息至系统地址空间,之后再将消息拷贝至接收方的地址空间。
  • 针对较长消息(大于256字节):这需要在发送方和接收方之间建立一个共享内存区域。发送方首先将消息存放在共享内存中,再向接收方发送一个通知(可以通过如上发送短消息的方式实现),之后再由接收方从共享内存中读取这一消息。
  • 当消息的数据量过大,难以放入共享内存时,服务端可以直接读取和写入客户端的地址空间。

高级本地过程调用(ALPC)拥有比以往的本地过程调用(LPC)更优的性能。因为LPC只能通过同步请求/应答机制通信,而ALPC还可以使用IOCP实现通信。这样,ALPC就可以在消息数量和进程数量间保持一定平衡,保证了端口的高速通信。此外,ALPC还允许信息的批量传输,减少了进程在用户模式内核模式之间的切换次数。

典型应用

本地过程调用在Windows NT及其衍生系统中得到了广泛应用。在Win32子系统中,LPC应用于客户端和子系统服务器之间的通信(CSRSS)。在Windows NT 3.51版本中引入了快速LPC以提高调用速度。然而由于NT4.0中将部分关键服务端移入内核模式(win32k.sys)以提高系统效能,这一方法已基本被摒弃。

本地安全认证子系统服务(LSASS),会话管理器(SMSS)以及服务控制管理器均使用LPC端口和客户进程直接通信。Winlogon安全引用监视器与LSASS进程之间的通信同样使用了LPC。

正如前文提到的,当消息在同一计算机内传输时,Microsoft RPC将调用LPC进行通信。许多仅在同一计算机内进行通信的服务采用LPC作为唯一的通信方式。远程对象连接与嵌入分布式组件对象模型的实现也在很多地方使用了LPC作为本地通信的方式。

参见

附注

参考文献

  • Dabak, Prasad; Borate, Milind; Phadke, Sandeep (1999), Undocumented Windows NT, Hungry Minds, ISBN 0-7645-4569-8 
  • Russinovich, Mark; Solomon, David; Ionescu, Alex (2009), Windows® Internals (5th ed.), Microsoft Press, ISBN 0-7356-2530-1 

外部链接