我正在实现一个消息传递算法。当消息在节点处具有足够的信息来组成消息时,消息在相邻节点之间传递 - 从相邻节点传递到节点的信息。如果我将每个消息都设置为一个线程并使用boost :: condition将线程置于休眠状态直到所需信息可用,那么实现是微不足道的。
不幸的是 - 我在图中有100k节点,这意味着300k线程。当我asked如何制作那么多线程时,答案是我不应该 - 而是重新设计。
我的问题是:是否存在等待条件的标准设计模式? 也许是一些异步控制模式?
编辑:我想我可以用proacator模式做到这一点。 我已经编辑了标签以包含boost :: asio - 以查看是否有人对此有任何建议。
所以讨论可以是具体的,这是迄今为止如何定义消息:
class
Message
{
public:
Message(const Node* from, Node* to)
: m_from(from), m_to(to)
{}
void
operator()()
{
m_to->ReceiveMessage( m_from->ComposeMessage() );
}
private:
Node *m_from, *m_to;
};
这些消息仿函数目前使用boost :: thread启动。然后我们有
class Node
{
Node(Node* Neighbour1, Node* Neighbour2, Node* Neighbour3);
// The messages (currently threads) are created on construction,
// The condition locks then sort out when they actually get passed
// without me having to think too hard.
void ReceiveMessage(const Message&);
//set m_message from received messages;
//EDIT This looks like an async write - use boost asio here?
Message
ComposeMessage()
{
// If possible I want to implement this function without threads
// It works great but it if every message is a thread
// then I have 300k threads.
// EDIT: this looks like an async read (use boost asio here?)
boost::mutex::scoped_lock lock(m_mutex);
while (!m_message) //lock the thread until parameter is set.
m_cond.wait(lock);
return *m_message;
}
private:
boost::optional<Message> m_message;
boost::mutex m_mutex;
boost::condition m_cond;
}
我喜欢代码的透明度,如果可能的话,想通过替换条件锁来保留相同的接口吗?
答案 0 :(得分:3)
我猜你要找的是reactor pattern。这是大多数活动不需要花费太多时间而且他们正在进行合作多任务处理的地方。有关该想法的JavaScript实现,请参阅node.js,但在C ++中,ACE library提供了开箱即用的概念,允许基于系统中核心数的多个线程。
这些库都依赖于某些支持磁盘,网络等非阻塞IO的操作系统API。当您不等待操作系统,而是应用程序中的其他消息源时,它们会为您提供相应的工具。