GUIs y threads

dagavi

Buenas, en un programa que estoy realizando, en C++, el cual dispone de una interfaz de consola (con ncruses) + salida de resultados a un archivo de texto (opcional), tengo el siguiente panorama:

Un thread que hay se encarga, cada segundo, de calcular unas estadísticas a partir de unos datos capturados (concretamente beacons wifi, que ya he escrito algunos pots sobre este tema por aquí, así lo relaciono xD) y, una vez está todo calculado, procede a actualizar las interfaces registradas con una especie de patrón observer, todo ello es el mismo thread, esquemáticamente hace:

 while (not fin) {
    for (red : redes) calcularStats(red);
    lista<Stats> stats = obtenerStats(redes);

for (gui : guis registradas) gui->actualizarInfo(stats);
sleep(1);
}

Como GUIs registro una que actualiza la consola, como dije con ncurses, y otra que escribe por archivo. En un futuro se pondrá una interfaz gráfica con Qt (y solo se pondría ncurses o Qt).

Como todo va muy rápido actualmente funciona a la perfección, sin embargo el tema de que la actualización de las GUI's sea síncrono con el resto del bucle no me termina de convencer. Si una "actualizarInfo(gui, stats)" tardara mucho, por ejemplo porque empezara a ordenar o a hacer cosas más complejas con los datos que se la pasan para mostrarlo todo más bonito podría ralentizar ese bucle.

Las GUI's típicamente se ejecutan con un thread aparte para evitar estas cosas, ahora bien, aquí mi pregunta: Teniendo en cuenta que esto puede tener varias GUI's (por decirlo de alguna forma) ¿cómo desincronizaríais todo esto? ¿Un thread que hiciera el último bucle, el de notificar, y que las llamadas a las guis fueran síncronas? ¿dejarlo como está y que sean las llamadas las que, de ser necesario, se curren un rápido retorno del control? (por ejemplo, la GUI que escribe en un archivo se puede dejar como está y que la ncurses cree un nuevo thread que sea el que se encargue de actualizar la consola, el actualizarInfo solo dejaría los datos en algún lado y notificaría que hay nueva info para que, cuando sea, el thread de ncurses recoja los datos y actualice la consola).

¿lo haríais de otra forma completamente distinta?

Saludos.

Khanser

Metes en un thread el calculo de estadísticas, en otro la GUI (que pinta la información a intervalos regulares), y cuando accedas a los datos comunes usa un mutex para bloquear el recurso mientras lo escribes / lees.

1
dagavi

Entonces básicamente la segunda forma, donde crearía un thread para ncurses (thread para la GUI) y el actualizar solo dejaría unos datos en un lado y notificaría de que hay nuevos datos, sería el thread ncurses el que se encargaría de pintar y hacer otras cosas. En un principio el mutex no me haría falta ya que los datos (en este caso las estadísticas) las paso con la llamada, en una estrategia push de información, por lo que se copian (y no se daría el caso de intentar pedir stats mientras se están calculando o cosas por el estilo).

Usuarios habituales

  • dagavi
  • Khanser