2011-05-20 10 views
10

¿Es posible, después de llamar a un hilo :: boost ejecutar algunas instrucciones, para volver al hilo principal?C++ boost :: thread execute code on main thread?

Mi código se basa en el patrón de proactor, sin embargo, una determinada función puede llevar un tiempo, por lo que para no bloquear todo el programa, estoy creando un hilo que ejecuta esta función. Cuando termina esta función, necesito llamar a otra función, pero debe ejecutarse en el hilo principal. Tengo un grupo de conexiones, que no es seguro para subprocesos, y realmente me gustaría evitar el mutex.

¿Hay una forma estable de ejecutar una función en el hilo principal (llamar a otro hilo)?

Al igual que en ObjectiveC performSelectorOnMaintThread

+0

Está buscando una cola de mensajes. –

+0

Por supuesto, si duerme en el hilo principal, bloquea el hilo principal. ¿Qué más esperarías? ¿Dormir para no trabajar como se anuncia? –

+0

(También, lo siento, me refiero a [message pump] (http://en.wikipedia.org/wiki/Event_loop)). –

Respuesta

2

Creo que es posible que desee ver en boost asio strands. Le permitirán especificar qué hilo (cadena) para hacer algo de wok, y automáticamente se pondrá en cola en ese capítulo.

Tenga en cuenta que un filamento es en realidad más como una fibra (es decir, si hay más hilos que los hilos reales, los hilos se multiplexarán en los hilos disponibles).

IIRC este no sin embargo le dará la oportunidad de especificar explícitamente el hilo principal 1. Sin embargo, la mayoría de las veces este no es el requisito real: lo que le permite hacer fácilmente es asegurarse de que las operaciones en un filamento se ejecutan en el mismo subproceso lógico, es decir, no es posible ninguna concurrencia dentro de un filamento.

Trivia: Boost Asio io_service.run() es un ejemplo de un mensaje de la bomba

Aquí está la página de muestras para Boost Asio: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html

+0

hilos parece muy prometedor. Sin embargo, si entiendo correctamente, debo hacer ConnectionPool Runnable y esperar hasta que se solicite (por ejemplo, para obtener una conexión), ¿cómo debo esperar, cond_wait con mutex? – TheSquad

+0

No sé nada acerca de su grupo de conexión. Se agregó un enlace a las muestras de Boost Asio – sehe

0

En las aplicaciones multitarea (al menos para mí) el hilo principal no hace mucho y todo se compensa con otros hilos creados al inicio. El hilo principal solo bloquea/espera (variable condicional) hasta que se le indique que estamos listos para salir. Todo el trabajo se invierte entre los hilos, lo que hace las cosas mucho más fáciles.

Y como sugiero anteriormente, la mejor manera de hacerlo es tener colas de mensajes (cada cola está envolviendo un subproceso o grupo de trabajadores) y puede publicar mensajes en uno u otro. Con las devoluciones de llamada y otros mecanismos de mensajería, puede hacer que su hilo "principal" envíe un mensaje a un hilo de trabajo para hacer el trabajo y proporcionar una devolución de llamada para enviar un mensaje al hilo "principal" cuando finalice con el resultado. Durante ese tiempo, el hilo "principal" puede continuar procesando otros mensajes y acciones mientras espera el resultado si tiene algún otro trabajo por hacer.

5

Si desea que una función se ejecute en el hilo principal, tendrá que implementar algún tipo de sistema de paso de mensajes. Entonces, por ejemplo, iniciaría su hilo principal y luego lanzaría el hilo de trabajo. El subproceso de trabajo haría su trabajo, mientras que el subproceso principal esperaría algún valor de retorno del subproceso de trabajo (es decir, el subproceso principal verificaría una cola de mensajes o algo de esa naturaleza). Cuando termina la cadena de trabajo, pasará a la cola de mensajes del hilo principal una estructura (es decir, un mensaje) con un puntero a la función que quiere que se ejecute el hilo principal.Sus mensajes pueden ser bastante simple:

struct message 
{ 
    typedef void (*func_ptr)(void); //or whatever your function signature would be 

    func_ptr function; 
    bool finished; 

    message(): function(NULL), finished(false) {} 
}; 

Por eso, cuando se realiza el subproceso de trabajo, se creará un nuevo mensaje, inicializar el puntero de función en el mensaje, y empujar ese mensaje de nuevo en la cola que el hilo principal es Esperando que. El hilo principal lee el mensaje de la cola y llama a la función.

BTW, y una forma efectiva de hacer que el hilo principal "espere" sin tener que mantenerlo en un bucle y utilizar ciclos de CPU sería usar un semáforo o variable de condición (como boost::condition) entre el hilo principal y el trabajador .

Y una nota más ... una "cola de mensajes" es simplemente un std::queue<message> con acceso de bloqueo apropiado que lee el hilo principal y el hilo de trabajo escribe. También puede haber otra cola de mensajes para el subproceso de trabajo en el que se escribe el subproceso principal, y el subproceso de trabajo se lee si necesita una comunicación bidireccional entre subprocesos.

0

En caso de que esté ejecutando en Visual Studio 2010, debería funcionar siempre en la depuración. Sin embargo, debido a un error, es posible que deba deshabilitar y luego volver a habilitar la "optimización" para que la liberación funcione.

0

Tuve una situación similar. diálogo mfc con subprocesos de refuerzo. para resolver agregué señales2 al hilo de refuerzo y las vinculé a las funciones de miembros en el diálogo. a medida que las señales ingresaron a las funciones del miembro del diálogo, verifiqué la identificación del hilo. si el id. del subproceso no era el mismo que el ID del subproceso del diálogo, insertaba una función de impulso en una cola de función estándar (la misma firma). onidle, kickidle Compruebo la cola y ejecuto las funciones.