Envoyé par
Ekleog
En faisant ça, tu déclares une unique variable currentState, qui a tous les types possibles. (enfin, state<int, int>, state<int, std::string>...)
Dès lors, comment le compilateur pourrait-il savoir quel est le réel type de la variable ?
Par ailleurs, j'ai oublié de mentionner un fait important : en général, on n'"externalise" pas les templates (je ne trouve pas de meilleur mot pour le dire).
C'est-à-dire que, pour faire simple (l'export existe bien, mais bon ...), les templates doivent être totalement disponibles au moment de leur utilisation, elles n'utilisent jamais un fichier cpp séparé - ce qui serait le cas avec extern mavar - tant qu'elles dépendent encore d'un paramètre template (il est possible de déplacer dans un .cpp une spécialisation state<int, int> ; mais pas une spécialisation partielle, par exemple).
J'espère que je suis compréhensible ...
Pour le multithread, le problème est que (avec le state inclus dans l'automate), celà signifierait que l'automate doit être verrouillé à *chaque* utilisation. Même si l'accès est en lecture seule. Parce qu'un programme qui accède à la fois en lecture et en écriture dans une variable contient une race condition, ce qui ferait tout planter.
Dans le cas du state stocké à part, il permet de ne verrouiller que les accès concurrents concernant le state, et non les accès concurrents (en lecture seule) concernant l'automate lui-même.
Par ailleurs, il y a un autre avantage à sortir l'état de l'automate : il est réutilisable en parallèle.
C'est-à-dire qu'on peut utiliser l'automate (une fois construit et avec les transitions bien définies) à partir de plusieurs threads, chaque thread ayant un état à lui ; et donc que l'automate peut être utilisé sur plusieurs états en même temps.
Ce peut être utile pour un programme de gestion de mots de passe, par exemple. Supposons que la validation du mot de passe se fasse par un automate. On veut pouvoir accepter des mots de passes de plusieurs sources : depuis un clavier et par ssh, par exemple.
Les mots de passe sont bien évidemment indépendants : si quelqu'un s'amuse à taper sur le clavier pendant qu'on s'identifie en ssh, on ne veut pas que le mot de passe soit considéré comme invalide !
Du coup, on utilise deux threads : un gérant le clavier, et un gérant la connexion ssh. Bien sûr, l'automate est créé avant la séparation des deux threads, à l'initialisation du programme.
Plutôt que de copier l'automate dans les deux threads, ce qui serait obligatoire si l'état était stocké dans l'automate, il est possible de conserver simplement les états dans les deux threads, sans influencer sur l'automate, et sans même avoir de perte de performance par l'utilisation d'un mutex, vu que l'automate est accédé en lecture seule.
En plus, tu y gagnes en performance ! Si l'automate est un peu gros (100.000.000 transitions et 10.000.000 d'états, chacun identifié par une string, par exemple, si on veut essayer de prendre une définition allégée de la langue française (exemple au hasard)), tu y gagnes énormément en temps de copie !
Bref, que du bénéfice à externaliser l'état de l'automate !