2017-05-19 5 views
1

J'utilise OpenMP pour effectuer une opération qui prend du temps. Je ne peux pas mettre à jour un ProgressBar de GTK + à partir de la boucle de temps en même temps que les opérations sont effectuées. Le code que j'ai updtates le ProgressBar, mais il le fait après que tout soit fait. Pas au fur et à mesure que le code progresse.Comment mettre à jour l'interface graphique GTK + en C++ avec des opérations qui prennent du temps?

Ceci est mon code fictif qui ne met pas à jour la barre de progression jusqu'à ce que tout soit fait:

void largeTimeConsumingFunction (GtkProgressBar** progressBar) { 

    int extensiveOperationSize = 1000000; 

    #pragma omp parallel for ordered schedule(dynamic) 
    for (int i = 0; i < extensiveOperationSize; i++) { 
     // Do something that will take a lot of of time with data 

     #pragma omp ordered 
     {   
      // Update the progress bar 
      gtk_progress_bar_set_fraction(*progressBar, i/(double)extensiveOperationSize); 
     } 

    } 
} 

Quand je fais la même chose, mais sans utiliser OpenMP, la même chose se produit. Il n'est pas mis à jour jusqu'à la fin.

Comment est-ce que je pourrais mettre à jour ce GTK + Widget en même temps que la boucle fonctionne?

Éditer: Ceci est juste un code fictif pour le garder court et lisible. Il a la même structure que mon code actuel, mais dans mon code actuel, je ne sais pas auparavant la taille des éléments que je vais traiter. Il pourrait y avoir 10 ou plus de 1 million d'objets et je devrai effectuer une action pour chacun d'entre eux.

+0

Indépendamment des problèmes de GTK +, vous devez utiliser '#pragma omp ordered' au lieu de' #pragma omp critical' dans la boucle si vous voulez que la barre de progression augmente de façon monotone! Bien que je ne recommanderais pas commandé, car il peut être décrémentiel à la performance. – Zulan

+0

Merci pour le conseil. Je vais le changer comme ça. Critique en effet n'est pas d'une manière ordonnée, mais je me demande ... Si j'ai déjà commandé ci-dessus, cela signifie-t-il que le critique est exécuté de manière ordonnée? Ou est-ce encore un fil qui entre aléatoirement dans cette région critique? En termes plus simples, je ne sais pas si la région ordonnée déclarée que j'ai créée couvre aussi cette région critique et en tant que telle, les threads accédant à la critique sont dans l'ordre. –

+0

Un 'parallel pour ordered' est sans signification sans construction' ordered'. – Zulan

Répondre

1

Il y a deux problèmes potentiels ici:

d'abord, si vous effectuez longs calculs en cours d'exécution qui pourrait bloquer thread principal, vous devez appeler

while (gtk_events_pending()) 
    gtk_main_iteration(); 

chaque maintenant et puis de garder l'interface utilisateur réactive (ce qui inclut se redessiner).

Deuxièmement, vous devriez call GTK+ functions only from main thread.

+0

Merci. Cela fonctionne comme prévu. –