Le principal produit de mon entreprise est une grande application monolithique C++, utilisée pour le traitement et la visualisation de données scientifiques. Sa base de code remonte à 12 ou 13 ans et, bien que nous ayons fait des efforts pour la mettre à jour et la maintenir (utilisation de STL et de Boost - lorsque j'ai rejoint l'entreprise, la plupart des conteneurs étaient personnalisés, par exemple - mise à niveau complète vers Unicode et la VCL 2010, etc. Comme il s'agit d'un programme de traitement et de visualisation de données, cela devient de plus en plus un handicap.
Je suis à la fois développeur y le chef de projet pour la prochaine version où nous voulons nous attaquer à ce problème, et cela va être un travail difficile dans les deux domaines. Je suis à la recherche des conseils concrets, pratiques et architecturaux sur la façon de s'attaquer au problème.
Le flux de données du programme pourrait ressembler à ceci :
- une fenêtre doit dessiner des données
- Dans la méthode de peinture, il appelle une méthode GetData, souvent des centaines de fois pour des centaines de bits de données en une seule opération de peinture.
- Il va calculer ou lire un fichier ou tout ce qui est nécessaire (souvent un flux de données assez complexe - imaginez que les données circulent dans un graphe complexe, dont chaque nœud effectue des opérations).
En d'autres termes, le gestionnaire de messages de peinture se bloque pendant le traitement, et si les données n'ont pas encore été calculées et mises en cache, cela peut prendre beaucoup de temps. Parfois, il s'agit de minutes. Des chemins similaires se produisent pour d'autres parties du programme qui effectuent de longues opérations de traitement - le programme ne répond pas pendant tout ce temps, parfois pendant des heures.
Je cherche des conseils sur la manière d'aborder le changement. Des idées pratiques. Peut-être des choses comme :
- des modèles de conception pour la demande asynchrone de données ?
- le stockage de grandes collections d'objets de telle sorte que les threads puissent lire et écrire en toute sécurité ?
- la gestion de l'invalidation des ensembles de données pendant que quelque chose essaie de les lire ?
- existe-t-il des modèles et des techniques pour ce genre de problème ?
- Qu'est-ce que je devrais demander et auquel je n'ai pas pensé ?
Je n'ai pas fait de programmation multithread depuis mes études universitaires il y a quelques années, et je pense que le reste de mon équipe est dans la même situation. Ce que je savais était académique, pas pratique, et est loin d'être suffisant pour avoir confiance dans cette approche.
L'objectif final est d'avoir un programme entièrement réactif, où tous les calculs et la génération de données sont effectués dans d'autres threads et où l'interface utilisateur est toujours réactive. Nous n'y arriverons peut-être pas en un seul cycle de développement :)
Editar: J'ai pensé que je devais ajouter quelques détails supplémentaires sur l'application :
- Il s'agit d'une application de bureau 32 bits pour Windows. Chaque copie fait l'objet d'une licence. Nous prévoyons d'en faire une application de bureau fonctionnant en local.
- Nous utilisons Embarcadero (anciennement Borland) C++ Builder 2010 pour le développement. Cela affecte les bibliothèques parallèles que nous pouvons utiliser, puisque la plupart semblent ( ?) être écrites uniquement pour GCC ou MSVC. Heureusement, ces derniers se développent activement et le support des standards C++ est bien meilleur qu'auparavant. Le compilateur supporte ces composants de Boost .
- Son architecture n'est pas aussi propre qu'elle devrait l'être et les composants sont souvent trop étroitement couplés. C'est un autre problème :)
Edit #2 : Merci pour les réponses jusqu'à présent !
- Je suis surpris qu'autant de personnes aient recommandé une architecture multiprocessus (c'est la réponse la plus votée pour le moment), et non le multithreading. J'ai l'impression que c'est une structure de programme très Unix, et je ne sais rien sur la façon dont elle est conçue ou fonctionne. Y a-t-il de bonnes ressources disponibles à ce sujet, sous Windows ? Est-ce vraiment si courant sous Windows ?
- En termes d'approches concrètes de certaines des suggestions de multithreading, existe-t-il des modèles de conception pour la demande et la consommation asynchrones de données, ou des systèmes MVP asynchrones ou threadaware, ou comment concevoir un système orienté tâche, ou des articles, des livres et des déconstructions après publication illustrant les choses qui fonctionnent et celles qui ne fonctionnent pas ? Nous pouvons développer toute cette architecture nous-mêmes, bien sûr, mais il est bon de travailler à partir de ce que d'autres ont fait auparavant et de connaître les erreurs et les pièges à éviter.
- Un aspect qui n'est pas abordé dans les réponses est la gestion de projet. J'ai l'impression qu'il est difficile d'estimer le temps que cela prendra et de garder un bon contrôle du projet lorsque l'on fait quelque chose d'aussi incertain que cela. C'est l'une des raisons pour lesquelles je recherche des recettes ou des conseils pratiques en matière de codage, je suppose, pour guider et limiter autant que possible la direction du codage.
Je n'ai pas encore marqué de réponse à cette question - ce n'est pas à cause de la qualité des réponses, qui est excellente (et merci), mais simplement parce qu'en raison de la portée de cette question, j'espère plus de réponses ou de discussions. Merci à ceux qui ont déjà répondu !