Non-threaded alternative to waiting on a condition. (Edit: Proactor pattern with boost.asio?)

戏子无情 提交于 2020-01-01 10:08:06

问题


I am implementing a message passing algorithm. Messages pass between adjacent nodes when they have enough information at the node to compose the message - information that is passed to the node from neighbouring nodes. The implementation is trivial if I make each of messages a thread and use boost::condition to put the thread to sleep until the required information is available.

Unfortunately - I have 100k nodes in the graph which would mean 300k threads. When I asked how to make that many threads the answer was that I shouldn't - and re-design instead.

My question is: is there a standard design pattern for waiting for a condition? Perhaps some asynchronous control pattern?

EDIT: I think I can do this with the proacator pattern. I have edited to tags to include boost::asio - to see if anyone has suggestions with this.

So the discussion can be concrete, here is how the messages are defined so far:

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;
};

These message functors are currently launched with boost::thread. Then we have

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;
}

I like the transparency of the code and if possible would like to keep the same interfaces by having some alternative to the conditional lock?


回答1:


I guess what you are looking for is the reactor pattern. This is where most of the activities do not take too much time and they are doing co-operative multitasking. See node.js for a JavaScript implementation of the idea, but in C++ the ACE library provides this concept out-of-the-box allowing multiple threads based on the number of cores in the system.

These libraries all depend on some OS APIs that support non-blocking IO on disks, network, etc. When you are not waiting for the OS, but another message source in your app, they provide you with the tools for that.



来源:https://stackoverflow.com/questions/5754228/non-threaded-alternative-to-waiting-on-a-condition-edit-proactor-pattern-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!