c – 用于管理加载到内存中的共享库的设计模式
gcc (GCC) 4.7.2 你好, 我正在开发一个大项目,它将包含我将开发的2个模块(共享库). 这些模块是我在C中创建的共享库,它们必须在彼此之间同步和交换消息. 管理器模块将控制这两个模块(.so)并将其加载到内存中.如果一个人失败了.经理可以尝试重新加载它. 我想知道这是我第一次做这样的事情.是否有可以遵循的设计模式? 所有这些都将用C语言编写并使用APR(Apache Portable Runtime)进行内存池管理,如果需要可能还有一些线程池. >启动管理器,将加载两个模块. 这些模块都将在运行Redhat的同一台机器上运行. 非常感谢任何建议. 解决方法
如果它在单个C进程中,这通常是一个坏主意 – 如果其中一个模块发生故障,您不太可能安全地卸载它,更不用说再次加载它.如果您需要能够从模块故障中恢复,则必须使用独立进程.代码仍然可以在.so文件中 – 只需fork()管理器一次,以便加载每个模块;例如,这是chrome plugins API使用的模型. 而且,处理组件故障本身就非常非常棘手.仅仅因为重新启动并不意味着B已经准备好与新重新启动的A进行通信.您可能希望尝试从erlang中收集一些想法,通过鼓励将应用程序分解为带有消息传递的子组件,可以非常好地处理组件故障.管理程序模块的层次结构以重新启动故障组件.如果你只有两个模块,这可能有点矫枉过正,但至少要考虑一下. 至于如何沟通,有许多范例.如果这些模块在同一个过程中,你可以只传递一个vtable.也就是说,例如: // moduleA.h struct vtable_A { void (*do_something)(); }; void set_vtable_B(struct vtable_B *); struct vtable_A *get_vtable_A(); void start_A(); // moduleB.h struct vtable_B { void (*do_something)(); }; void set_vtable_A(struct vtable_A *); struct vtable_B *get_vtable_B(); void start_B(); 您的经理将加载两者,将vtable从A传递给B,反之亦然,然后调用启动例程.小心订购 – 要么必须在B准备好之前启动A,要么反之亦然,他们需要对此有所帮助. 如果它们处于独立进程中,则通常可以通过消息传递.它本质上是一个网络协议 – 您的子进程将序列化消息发送给管理器,管理器将它们路由到其他子进程.谈话可能看起来像这样: MGR->A START MGR->B START A->MGR REGISTER_ENDPOINT 'ProcessA' A->MGR WATCH_ENDPOINT 'ProcessB' MGR->A OK_REGISTER 'ProcessA' MGR->A OK_WATCH 'ProcessB' B->MGR REGISTER_ENDPOINT 'ProcessB' B->MGR WATCH_ENDPOINT 'ProcessA' MGR->B OK_REGISTER 'ProcessB' MGR->A NEW_ENDPOINT 'ProcessB' A->MGR APPLICATION_DATA TO:'ProcessB',PAYLOAD:"Hello,world!" MGR->B OK_WATCH 'ProcessA' MGR->B NEW_ENDPOINT 'ProcessA' MGR->B APPLICATION_DATA FROM:'ProcessA',world!" 请记住,除了上面的示例之外,还有许多其他方法可以构建这种协议,并在消息传递协议之上构建RPC.您可能有兴趣查看诸如DBUS(您可以直接使用!)或DCOM之类的东西,这些之前已经完成了这类工作.除此类协议之外的其他优化包括使用管理器在A和B之间建立某种直接通道,并且只有在需要重新启动A或B时再次使用它. 也就是说,在弄清楚需要做什么之前,不要过于深入了解经理如何运作的细节.设计插件< - >管理器高级接口,插件< - >插件协议;然后才设计插件< - >管理器界面的细节.这很容易让人陷入困境,最终变得像CORBA或SOAP那样过于复杂. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |