Avec les threads, comment dois-je gérer quelque chose qui devrait idéalement se dérouler dans un ordre séquentiel?

J’ai un générateur d’image qui gagnerait à fonctionner en threads. J’ai l’intention d’utiliser des threads POSIX et j’ai écrit un code de maquette basé sur https://computing.llnl.gov/tutorials/pthreads/#ConVarSignal pour tester les éléments.

Dans le programme prévu, lorsque l’interface graphique est utilisée, je souhaite que les lignes générées apparaissent une par une de haut en bas (la génération d’images peut être très lente).

Il convient également de noter que les données générées dans les threads ne sont pas les données d’image réelles. Les données de fil sont lues et transformées en données RVB et placées dans le tampon d’image réel. Et dans l’interface graphique, la façon dont les données générées par le fil sont converties en données RVB peut être modifiée pendant la génération d’image sans arrêter la génération d’image.

Cependant, l’ordonnanceur de threads ne garantit pas que les threads fonctionneront dans l’ordre que je veux, ce qui rend malheureusement les transformations des données générées par les threads plus complexes, ce qui implique la solution indésirable consistant à conserver un tableau contenant une valeur bool indiquant les lignes. sont fait.

Comment devrais-je gérer cela?

Actuellement, j’ai un fil conducteur à signaler lorsque l’image est terminée (ce qui devrait être une barre de progression, mais je n’ai pas encore atteint cet objective, il utilise plutôt pthread_cond_wait ). Et plusieurs fils de rendu faisant while(next_line());

next_line() effectue un locking mutex et obtient la valeur de img_next_line avant de l’incrémenter et de déverrouiller le mutex. il restitue ensuite la ligne et effectue un locking mutex (différent du premier) pour obtenir lignes_done en fonction de la hauteur, des signaux si complets, déverrouille et renvoie 0 si complet ou 1 sinon.

Étant donné que les threads peuvent bien s’exécuter en parallèle sur différents cœurs, il est presque inévitable que les résultats arrivent en panne. Je pense que votre façon de suivre ce qui est complet avec un ensemble de drapeaux est tout à fait raisonnable.

Il est possible que l’effet global soit plus agréable si vous utilisez des threads d’une granularité différente. Dites à chaque fil (disons) 20 lignes sur lesquelles travailler plutôt que 1. Ensuite, à la fin, vous disposerez de blocs plus gros pour dessiner, et peut-être que dessiner des rayures vous ira?

Acceptez simplement que les lignes se feront dans un ordre non déterministe; il semble que cela se produise car leur temps de rendu est très long. Dans ce cas, forcer un ordre d’achèvement gaspillera du temps CPU.

Cela peut sembler idiot, mais en tant qu’utilisateur, je ne veux pas voir une ligne être lue lentement de haut en bas. Un processus lent semble encore plus lent, car l’utilisateur a déjà complètement prévu ce qui se passera ensuite. Il est préférable de simplement effectuer le rendu quand il est prêt, même s’il est dispersé à l’endroit (soit en lignes simples, soit mieux en blocs, comme certains l’ont suggéré). Cela rend l’apparence plus aléatoire et donc plus captivante et moins ennuyeuse pour un utilisateur comme moi.