Pregunta

¿Hay alguna forma de integrar Boost.Asio con Qt4 (preferido) o el bucle principal GTK? GTK proporciona una encuesta (2) como API, por lo que técnicamente debería ser posible. Qt proporciona su propia capa de red, sin embargo, prefiero usar el código existente escrito para Boost.Asio. Quiero integrarlos sin usando un hilo adicional.

¿Hay alguna referencia sobre cómo hacer esto para Qt4 (preferido) o GTKmm?

Gracias.

Editar

Quiero aclarar varias cosas para facilitar la respuesta. Tanto Qt como GTKmm proporcionan " seleccione como " funcionalidad:

Entonces, la pregunta es cómo integrar los "selectores / sondeos" existentes como reactor para Boost.Asio io_service . Hoy, Boost.Asio puede usar select, kqueue, epoll, / dev / poll y iocp como servicio de reactor / proactor. Quiero integrarlo al bucle principal del marco GUI.

Cualquier sugerencia y solución (mejor) son bienvenidas.

¿Fue útil?

Solución

Es una pregunta bastante antigua, pero para aquellos que la están leyendo ahora me gustaría compartir mi código , que es una implementación de QAbstractEventDispatcher para boost :: asio.

Todo lo que necesita es agregar la siguiente línea antes de crear QApplication (generalmente está en main ()).

QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));

Causará que io_service se ejecute junto con la aplicación qt en un hilo sin latencia adicional y caída de rendimiento (como en la solución con la llamada a io_service :: poll () " de vez en cuando ").

Desafortunadamente, mi solución es solo para sistemas posix, ya que usa asio :: posix :: stream_descriptor. El soporte de Windows puede necesitar un enfoque completamente diferente o bastante similar. Realmente no lo sé.

Otros consejos

Simple: Cree una ranura QT que llame al io_service :: poll_one () que pertenece a la interfaz gráfica de usuario. Conecte esa ranura a la señal tick de QT.

en profundidad: Por suerte para ti Boost.Asio está muy bien diseñado. Hay muchas opciones sobre cómo proporcionar un hilo de ejecución a las partes internas asíncronas subyacentes. La gente ya ha mencionado el uso de io_service :: run () , una llamada de bloqueo con muchas desventajas.

Solo se le permite acceder a widgets gui desde un solo hilo. Los hilos externos generalmente necesitan publicar eventos en la interfaz gráfica de usuario si quieren mutar cualquier widget. Esto es muy similar a cómo funciona Asio.

El enfoque ingenuo es dedicar solo un hilo (o temporizador) a ejecutar io_service :: run () y hacer que el controlador de finalización de Asio publique una señal gui. Esto funcionará .

En su lugar, puede usar la garantía de que los controladores de finalización solo se llamarán en el hilo de ejecución de la persona que llama io_service . No haga que el hilo de la interfaz gráfica de usuario llame a io_service :: run () ya que está bloqueando y podría bloquear la interfaz gráfica de usuario. En su lugar, use io_service :: poll () o io_service :: poll_one () . Esto hará que se llame a los controladores de finalización de Asio pendientes desde el hilo de la interfaz gráfica de usuario. Como los controladores se ejecutan en el hilo de la interfaz gráfica de usuario, pueden modificar los widgets.

Ahora necesita asegurarse de que el io_service tenga la oportunidad de ejecutarse regularmente. Recomiendo que se repita una llamada de señal gui poll_one () varias veces. Creo que QT tiene una señal de tic que haría el truco. Por supuesto, podría rodar su propia señal QT para obtener más control.

Si entiendo su pregunta correctamente, tiene un código escrito para Boost.Asio. Le gustaría usar ese código dentro de una aplicación GUI.

Lo que no está claro en su pregunta es si desea envolver las capas de red Qt / Gtk a través de asynio para que su código funcione, si solo está buscando una solución para tener un bucle de eventos gui y asynio juntos.

Asumiré el segundo caso.

Tanto Qt como Gtk tienen métodos para integrar eventos foráneos en su ciclo de eventos. Consulte, por ejemplo, qtgtk donde el bucle de eventos Qt está conectado a Gtk.

En el caso específico de Qt, si desea generar eventos para Qt, puede usar la siguiente clase: QAbstractEventDispatcher .

Después de echar un vistazo rápido a boost asio, creo que debe hacer lo siguiente:

  • tiene un QTimer recurrente con duración cero que llama a io_service :: run () todo el tiempo. De esa manera, boost :: asio llamará a su controlador de finalización tan pronto como se complete su operación asincrónica.
  • en su controlador de finalización, dos opciones:
    • si su operación de finalización es larga, separada de la GUI, haga su negocio y asegúrese de llamar a qApp.processEvents () regularmente para mantener la GUI receptiva
    • si solo quieres comunicarte con la interfaz gráfica de usuario:
      1. defina un tipo QEvent
      2. personalizado
      3. suscríbase a este evento
      4. publique su evento en el bucle de eventos Qt usando QCoreApplication :: postEvent ( ) .

La integración genuina de los bucles principales es posible. Es solo un gran dolor (y aún no lo he probado).

Ejecutar io_service :: run () en un hilo separado es probablemente el camino a seguir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top