如何实现不阻止其用户的引擎类
Posted
技术标签:
【中文标题】如何实现不阻止其用户的引擎类【英文标题】:How to implement engine class which doesn't block its user 【发布时间】:2016-01-21 10:49:41 【问题描述】:我有类,我们称之为“引擎”,它包含类似事件循环的东西,其逻辑可以用以下伪代码解释:
for(;;)
int interruptId;
waitForInterrupt(); // blocking wait
switch(interruptId)
case REQUEST_DATA:
doSomeStuff();
...
事件循环用于中断处理(来自硬件设备的驱动程序)。 引擎将由客户使用。客户端应该能够启动/停止引擎。 但启动引擎不应暂停客户端。
我的意图:引擎启动时会启动一个新线程,在该线程中执行事件循环 for(;;)。
问题是一种解决方案吗,您能否提出适用于这种情况的现有设计模式,关于实现的任何建议以及我应该考虑的可能的瓶颈。
注意!!!更新:引擎类作为动态库提供给客户端
【问题讨论】:
如果您的客户端已经有一个事件循环,如果您想避免额外的线程,您可以将引擎事件循环合并到其中。 Engine 类作为单独的动态库提供给客户端,所以我无法合并它们的循环 "merge" 可能是一个不好的词选择——“call from”怎么样——即。对于每个客户端事件循环迭代,您还检查引擎是否有未决事件(如果有,则处理引擎事件 - 如果没有,您只需执行下一个客户端循环迭代)。 这不起作用,因为引擎循环包含阻塞调用,因此客户端也将被阻塞,直到驱动程序的下一个中断,这不是我想要的一种行为 如果引擎库不提供任何可以让您将两个事件循环合并为一个的功能,您就不得不拥有两个线程(每个事件循环一个线程)。跨度> 【参考方案1】:#include <thread>
#include <functional>
#include <vector>
#include <iostream>
#include <memory>
#include <cassert>
struct MsgFromAgent
std::string str;
;
struct MsgToAgent
std::string str;
;
struct IClient
virtual void onMsgFromBC(MsgFromAgent& msg) = 0;
virtual void onTimeout() = 0;
virtual ~IClient() ;
;
struct Engine
Engine(IClient& client) : isRunning(false), client(client)
~Engine()
// we expect that if client started the engine
// client must stop it before Engine will be destructed
assert(!isRunning && "Running engine should be stoped by the client");
// in any way, handle exceptional situation if it arises
if(isRunning)
isRunning = false;
th.join();
void start()
isRunning = true;
th = std::thread(std::bind(&Engine::eventLoop, this));
bool write(const MsgToAgent& msg)
// some code
void stop()
isRunning = false;
th.join();
void eventLoop()
while(isRunning)
// blocking calls, that return control when certain interrupts from hardware arrives
// if interrupt haven't arraived within certain time limit:
try
client.onTimeout();
catch(...)
// interrupt about incomming msg:
MsgFromAgent dummyMsg;
try
client.onMsgFromBC(dummyMsg);
catch (...)
bool isRunning;
std::thread th;
IClient& client;
;
struct Client : public IClient
Client() : e(*this)
;
~Client()
void onMsgFromBC(MsgFromAgent& msg)
std::cout << "On message\n";
void onTimeout()
std::cout << "On timeout\n";
Engine e;
;
int main()
Client c;
return 0;
【讨论】:
以上是关于如何实现不阻止其用户的引擎类的主要内容,如果未能解决你的问题,请参考以下文章