技术开发 频道

面向模式的软件架构:并发

    ◆◆◆

    并发通过允许组件同时处理多个客户端请求而不必阻塞来提高软件服务质量。然而,如何在软件中表现并发单元,以及如何在运行中与之交互,则是由开发人员决定的。

    尤其,对于客户端来说,它应该能够随时向组件发出请求,而不必等着其他请求执行完毕。我们需要能够根据请求的优先级或者截止时间等特征调度客户端请求的执行。为了保证服务请求的独立性,它们的串行化和调度对组件和客户端都应该是透明的,以便在对软件实现进行重用的时候不必考虑它们是否要求不同的同步策略。

    因此:

    将并发单元界定为组件上的服务请求,并且让它和请求的客户端在不同的线程上运行。使客户端和组件可以异步地交互来产生和使用服务结果。

    客户端可以通过调用组件暴露给客户端线程接口上的方法初始化组件上的服务请求。设计组件接口的时候不必受同步的约束,在发出请求之后立刻把控制返回给客户端。将请求对象化,并传递给运行在一个或多个单独线程上的组件实现,让组件实现独立地调度服务请求的执行,而不依赖于何时对请求对象进行的初始化。此外,在服务结束后还要为组件提供将结果返回给客户的机制。

    ◆◆◆

    ACTIVE OBJECT设计通过允许客户端线程和服务请求同时运行来增强应用程序中的并发性。在服务请求执行的过程中客户端并不会被阻塞。而且,通过使用调度器减少了同步的复杂性,调度器可以根据一定的同步约束机制来达到对组件实现的串行化访问。从实际组件实现中将需求调度分离出来,这样我们的组件就可以在不要求同步的情形中重用。同时有些组件可能并不是为并发访问设计的,这种分离机制使它们可以在并发的应用中使用。最后,服务请求的执行顺序可以与服务请求的调用顺序不同,这样在采用优先级排序、截止时间和其他的同步约束时就更加方便了——不过这样做会使得调试更为复杂。ACTIVE OBJECT也会引入比较重量级的请求处理和执行基础设施,这对那些只实现短暂方法的组件会导致性能上的损失。

    使用EXPLICIT INTERFACE(281)将组件的接口暴露给客户端线程。从客户端的角度来看就跟组件位于客户端线程内是一样的。设计接口的时候要确保方法签名中不包含同步参数。这样即使并发组件是由多个客户端线程共享的,从客户端看来就像自己拥有独占的访问一样。

    在运行时,组件接口将所有的方法调用对象化为服务请求——这通常使用COMMAND(435)来实现——并使用它来完成相应的方法调用的同步约束机制。请求的对象化将服务请求和服务执行在时间和空间上进行了解耦合,这样当客户端调用组件上的服务时就不需要阻塞自己或其他的客户端。将创建的服务请求存储到一个共享的活动列表中,该列表维护了并发组件上所有挂起的服务请求。这个活动列表用MONITOR OBJECT(368)实现,可以确保并发访问是线程安全的。

    组件的实现可以有一个或多个宿主线程。在每个线程中,有一个实现组件的功能servant。调度器将服务请求对象从共享的活动列表中分离出来,然后在servant上执行。这样的设计允许服务请求和执行并行地运行,也就是说,服务请求在客户端线程中调用,而服务执行则运行在不同的线程中。而且,调度器将组件功能从调度和同步机制中分离出来,使得双方都可以独立的开发和改进。

    将调度器设计为COMMAND PROCESSOR(343)可以实现组件的事件循环(event loop)。它负责检查活动列表,发现可执行的服务请求后将其从活动列表中移除,并在servant上执行这个服务请求。我们还可以使用TEMPLATE METHODS(453)和STRATEGIES(455)来支持多种调度策略。TEMPLATE METHODS适用于调度器配置可以在编译期确定的情况。相反,STRATEGIES则支持在运行时配置和重配置调度策略。

    客户端可以通过FUTURE(382)获得并发组件上的服务请求结果。在服务调用之后,并发组件的接口将future返回给客户端,在servant完成服务执行之后,由关联的服务请求填充future。如果客户端在获得服务结果之前访问future,客户端可以阻塞或者轮询等待,直到服务结果有效。如果我们不再使用future,可以通过AUTOMATED GARBAGE COLLECTION(517)安全地将其回收——如果编程语言支持的话,否则,如果必须手动编码回收可以使用COUNTING HANDLE(522)。

    15.4 Monitor Object **

    在开发SHARED REPOSITORY(202)架构,REQUESTOR(242)、CLIENT REQUEST HANDLER(246)、MESSAGE CHANNEL(224)、MESSAGE ROUTER(231)分布式基础设施,ENCAPSULATED IMPLEMENTATION(313),ACCEPTOR-CONNECTOR(265)结构(?arrangement,有没有更好的词语),HALF-SYNC/HALF-ASYNC(359)、LEADER/FOLLOWERS(362)或者ACTIVE OBJECT(368)并发模型的时候…

    …我们必须考虑对象要能够被多个线程共享。

0
相关文章