2011-04-22 11 views
6

Estoy implementando un algoritmo de paso de mensajes. Los mensajes pasan entre los nodos adyacentes cuando tienen suficiente información en el nodo para componer el mensaje, información que se pasa al nodo desde los nodos vecinos. La implementación es trivial si hago que cada mensaje sea un hilo y uso boost :: condition para poner el hilo en modo de espera hasta que esté disponible la información requerida.Alternativa sin hilos a la espera de una condición. (Editar: Patrón Proactor con boost.asio?)

Lamentablemente, tengo 100k nodos en el gráfico, lo que significaría 300k hilos. Cuando hice asked cómo hacer tantos subprocesos, la respuesta fue que no debería, y rediseñé en su lugar.

Mi pregunta es: ¿hay un patrón de diseño estándar para esperar una condición? Quizás algún patrón de control asincrónico?

EDIT: Creo que puedo hacer esto con el patrón proacator. He editado las etiquetas para incluir boost :: asio, para ver si alguien tiene sugerencias al respecto.

Así que la discusión puede ser concretos, aquí es cómo los mensajes se definen hasta el momento:

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

Estas palabras funcionales de mensajes se ponen en marcha en la actualidad con impulso :: hilo. Entonces tenemos

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

me gusta la transparencia del código y si es posible le gustaría mantener las mismas interfaces por tener alguna alternativa al bloqueo condicional?

+0

Parece que estás reinventando más o menos CSP. ¿Qué hay de encontrar una biblioteca de CSP que hace todo esto por usted? – jalf

+0

@Jaif - Creo que tienes razón. No había oído hablar de CSP (sabía que no hacerlo me llevaría a la informática). Parece que tengo algo de google para hacer ... – Tom

Respuesta

3

Supongo que lo que estás buscando es reactor pattern. Aquí es donde la mayoría de las actividades no toman demasiado tiempo y están haciendo multitareas cooperativas. Consulte node.js para una implementación de JavaScript de la idea, pero en C++, el ACE library proporciona este concepto listo para usar que permite varios subprocesos según la cantidad de núcleos en el sistema.

Todas estas bibliotecas dependen de algunas API de OS que admiten IO no bloqueante en discos, redes, etc. Cuando no está esperando el SO, sino otro origen de mensajes en su aplicación, le proporcionan las herramientas para eso .

+0

gracias, un artículo muy interesante y la biblioteca Ace parece que podría hacer el truco. – Tom