我们需要构建一个软件框架(或中间件),以便在单个机器上运行的不同软件组件(或模块)之间实现消息传递。该框架将提供以下功能:
根据上述要求,以下哪种方法是正确的(有其推理)?:
在消息来源方面,有一些明显的缺点和优点。优点:
我赞成Option-2,但我不确定我的论点是否足够稳固。你有什么看法?
编辑:根据要求澄清,这里有更多的规范细节:
答案 0 :(得分:5)
以下是我能想到的:
多进程(1)与单进程,多线程(2):
答案 1 :(得分:1)
听起来您正在实施通信顺序进程。优良!
首先处理线程与进程,我会坚持线程;上下文切换时间更快(特别是在进程上下文切换非常慢的Windows上)。
其次,共享内存与消息队列;如果你正在进行完整的同步消息传递它将对性能没有任何影响。共享内存方法涉及一个共享缓冲区,该缓冲区由发送方复制并由读取器复制。这与消息队列所需的工作量相同。所以为了简单起见,我会坚持使用消息队列。
实际上您可能想考虑使用管道而不是消息队列。你必须编写代码来使管道同步(它们通常是异步的,这将是Actor Model;消息队列通常可以设置为零长度,它可以实现你想要的同步和正确的CSP),但是你可以像使用套接字一样轻松。然后,您的程序可以在需要时进行多机分发,但您根本不必更改架构。在进程之间也命名管道是一个等价的选项,因此在进程上下文切换时间良好的平台(例如linux)上,整个线程与进程问题消失了。因此,使用管道更加努力,为您提供了非常重要的可扩展性选项。
关于崩溃;如果你进入多进程路由并希望能够优雅地处理进程的失败,那么你将不得不做一些工作。基本上,你需要在消息传递通道的每一端都有一个线程来监视另一端的响应(可能是通过在它们之间来回反弹保持唤醒消息)。这些线程需要将状态信息提供给它们相应的主线程,以便在另一端未按时发送保持唤醒时告诉它。然后主线程可以相应地行动。当我这样做时,我让监视器线程自动重新连接(例如远程进程已经恢复生命),并告诉主线程。这意味着我的系统中的各个部分可以来来去去,其余部分只是很好地应对。
最后,您的实际应用程序进程将最终作为循环,顶部的select()等待来自所有不同通道(和监视器线程)的消息输入。
顺便说一下,在Windows中实现这种事情是令人沮丧的。在任何Microsoft语言中,任何地方都没有恰当的select()。有一个用于套接字的select(),但你不能像在Unix中那样在管道等上使用它。 Cygwin的家伙在实现他们的select()版本时遇到了实际问题。我认为他们最终得到了每个文件描述符的轮询线程;效率极低。
祝你好运!答案 2 :(得分:0)
您的问题缺乏对“模块”如何实施以及它们的作用的描述,并且可能描述了您计划实施所有这些的环境。
例如:
还有更多事情需要考虑。如果您只是在模块之间传递数据,谁说您的系统需要使用多个线程或多个进程?还有其他架构在没有它们的情况下执行相同的操作,例如使用回调事件驱动(消息接收器可以向系统注册回调,在消息生成器生成消息时调用)。在并行性不重要且可以在调用者的执行上下文中调用接收代码的情况下,这种方法绝对是最快的。
tl;博士:你的问题只是表面上的问题:)