Plop,
dans le cadre de mon projet j'ai réalisé un Task Manager qui marche très bien, qui est même très rapide parce qu'il a très peu de fonctionnalités.
En gros, on lui donne une tâche a faire, il la place dans une queue. Un thread disponible prend la tâche, soit l'éxécute si elle est atomique ou bien la coupe en deux morceaux plus petit, poste les deux morceaux et se rendort.
La synchronisation est très simple, c'est un simple sémaphore qui est incrémenté lorsqu'une täche est postée, et decrémentée lorsqu'une tâche est retirée (donc si il n'y a rien a faire, les threads dorment)
les taches sont dans une pile atomique () enfin une pile (et pas une queue malheureusement) ou ajouter et retirer sont des opérations atomiques.
Tout ca marche très bien et vu la simplicité du concept, c'est très efficace et il y a peu de synchro entre les threads, presque pas de blocage.
Il y a un thread par coeur sur la machine donc tout marche nickel.
Mais j'ai été confronté a un problème très ennuyeux récemment: sur windows (et sur mac surtout d'ailleurs) le thread principal est "spécial", il a la gestion de la souris/clavier, et donc toutes les commandes OpenGL/DirectX et toutes les opérations sur les fenêtres devraient s'effectuer sur ce thread.
Bon la ou j'ai été ennuyé au début c'est que le thread principal n'est même pas capable d'executer des tâches; il créait tous les autres threads, envoyait le premier job et se reposait (ce flemmard). Les autres jobs postent d'autres jobs postent d'autres jobs a leur tour, etc, perpétuant ainsi la chaîne de la vie.
Bon j'ai donc changé pour que le thread principal soit dans les threads "worker", maintenant j'en suis a un autre problème: comment dire q une tâche de s'executer sur un thread en particulier? Ce que j'ai fait pour l'instant c'est ajouter une enumeration Affinity { MainThread, DontCare };donc soit on s'execute sur le thread principal, soit on s'en fout.
Le problème c'est que le thread principal il branle rien (cte flemmard) en attendant une tâche spécialement pour lui; en effet, soit on est en affinité DontCare et on s'execute sur les threads 2, 3, 4..., soit on est en MainThread et on s'execute sur le thread principal. Du coup le trhead principal n'aide pas du tout a la parallelisation, lorsqu'il a rien a faire j'aimerai qu'il participe aux tâches ménagères aussi!
je me demande donc comment on peut faire de manière efficace une implémentation d'un task manager avec une affinité; avec un seul semaphore, comment on peut reveiller le bon thread? si on reveille un thread au pif, ca marche pas.
J'ai pensé a un truc, WaitForMultipleObjects, sur Windows, qui me permettrait d'écouter deux semaphores en meme temps, mais coomment faire sur macOS ou linux?
d'utres idées géniales?
Partager