le 11-05-2013 06:50 AM
Il n'est pas "interdit de" ... il est "déconseillé de" ... (parceque ceci,cela ..)
Pour éteindre ton PC tu peux aussi retirer la prise de courant.
Si ton PC est en feu, c'est probablement la meilleure solution.
Mais si tout se passe bien, n'y a-t-il pas "plus propre" pour le faire ?
le 11-05-2013 06:59 AM
Il serait intéressant de connaître le contenu de Stop Timed Structure.vi que NI met à disposition pour arrêter l'exécution des Timed Loop. Malheureusement, le code de ce VI est protégé par mot de passe.
Dans leur exemple J1939, NI utilise une FGV pour arrêter les boucles multiples. Comme cela est bien connu et démontré par cet exemple, l'avantage d'une FGV par rapport à une variable locale (en plus de pouvoir être utilisée dans d'autres VIs) est de pouvoir y inclure de "l'intelligence". Pour vous éviter de devoir télécharger les nombreux VIs de cet exemple, j'attache la FGV et son ctl en LV2012. Des captures d'écran du code montrant comment elle est utilisée se trouvent dans la documentation référencée ci-dessus.
le 11-10-2013 06:56 AM
@Eric :
"Chaque structure événement gère sa propre file d'attente d'événements,
les boucles vont donc déclencher et s'exécuter en même temps ..."
Je pense que "là" tu parlais d'Event statique, (value change, etc ...)
c.a.d non généré par un "Generate User Event" ... (cas des Event dynamiques)
J'ai remarqué que dans le cas des Event Dynamiques, une file d'attente n'est pas liée à une Structure_Event,
mais à la Reference créée par le "Register for Event".
Autrement dit, pour avoir 2 Piles indépendantes pour 2 Structures Event, chacune doit avoir sont "Register for Event" en propre.
Si on cable 2 structures Event sur la même Ref "register for Event" ... la Pile est commune.
Eric ... cela est sans aucun doute évident pour toi !
Je ne t'explique pas
je fais simplement part de mes constatations pour ceux qui suivent le sujet,
et qui comme moi ... découvrent tous les jours.
11-11-2013 08:42 AM - modifié 11-11-2013 08:42 AM
Hello,
Non je persiste et signe sur ma phrase, chaque structure événement gère sa propre file d'attente. Les refnums d'enregistrement permettent d'indiquer à quelle file d'attente les fonctions Generate User Event (en fait, le refnum du user event) seront associées. Les refnums d'enregistrement ne constituent pas à eux seuls une file d'attente...
Pour le reste, tu as raison :-]
Voyons plutôt ça comme des bretelles d'autoroute (je viens de rouler 5 heures, j'ai pas trouvé mieux comme analogie, sorry) : les routes secondaires - refnums d'enregistrement dynamique - sont associés à une autoroute. Si la même route secondaire rejoint une autre autoroute plus loin, une même voiture n'ira surement pas dans les 2 autoroutes...
Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.
11-11-2013 11:39 AM - modifié 11-11-2013 11:49 AM
@Eric :
Ne parlons pas de "l'utilité" ou non du "code_test" que voici,
prenons le simplement sur un plan purement théorique.
si chaque structure Event a sa propre file d'attente ...
pourquoi le code ci-dessous (et ci-joint) ne génère-t-il pas le même nombre d'event dans chaque structure event. (??)
action : boolean_1 value change
event : <toto> user event (dans chaque structure event)
"boolean_value_change" devrait placer un "toto_user_event" sur la pile de chaque structure_event,
et "l'event_toto" de chaque structure devrait donc être actionné à chaque boolean_value_change.
ce n'est pas le cas ... les 2 nombres (N_1 et N_2) ne sont pas les mêmes (?)
le 11-11-2013 03:14 PM
Comme dit dans mon précédent poste, ton code s'explique et est normal, pas de souci à ce niveau-là (FYI, si le timeout est proche de 0, on devrait voir peu de différence entre les comptages).
Mais en mémoire, un refnum d'enregistrement ne détient pas de file d'attente, ce sont les structures événement qui l'ont. Le fait d'enregistrer un événement le dédie à une structure événement et revient à créer une callback. Les callbacks n'ont pas de file d'attente intégrée, elles s'exécutent si leur thread de déclenchement est disponible et si le code de la callback n'est pas réservé ! Pareil ici 🙂
Cdt,
Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.
11-11-2013 05:49 PM - modifié 11-11-2013 05:57 PM
@Eric :
petit préambule :
toutes mes excuses d'insister.
je ne cherche pas, comme on dit, à faire "le malin" ... mon seul but est de comprendre, sois en bien certain.
Application Engineer Specialist, chez NI ... il est bien certain que tu sais de quoi tu parles.
Ce qui suit n'est pa une explication (pour qui ?) il s'agit simplement de mes propres réflexions.
oui, un Register_for_events, à lui tout seul, ne crée aucune pile ... mais uniquement une Référence.
C'est quand on cable cette référence sur le dynamic_event_terminal d'une structure event que l'on crée une pile.
Une structure event possède "d'office" une pile pour les static_event, et le fait de cabler son terminal dynamique
à une Reference d'enregistrement d'événement en crée une deuxième.
voici quelques phrases de la doc NI à ce sujet
Each Event structure and Register For Events function on the block diagram owns a queue that LabVIEW uses to store events.
An Event structure handles all events in its queue and the events in the queues of any Register For Events functions that you wired to the dynamic event terminals of the Event structure. LabVIEW uses these queues to ensure that events are reliably delivered to each registered Event structure in the order the events occur.
Si je fais ceci :
J'ai uniquement des static_event.
Dans ce cas, chaque structure event à sa propre pile, indépendante de la pile de l'autre structure
Et de fait ... je peux cliquer sur le bouton autant que je veux ... je n'ai jamais de différence entre N_1 et N_2
ici aussi ...si je fais ceci :
Aucun problème, je clique 200x, jamais de différence entre N_1 et N_2.
Ce n'est pas "Register_for_events" qui crée une pile ... c'est la connection de sa Reference sur un Terminal dynamique.
Register_for_events + Terminal dynamique = pile dynamique.
Et ici, j'ai crée 2 piles dynamiques distinctes, d'où pas de soucis entre N_1 et N2.
Mais si je fais ceci :
Alors là, les ennuis commence, N_1 et N_2 sont totalement différents.
Je n'ai crée qu'une seule pile dynamique commune à deux structure event ... race condition sur cette pile.
Une seule pile dynamique pour 2 Structure Event ...
on s'écarte du principe qu'une pile d'événement est la "propriété" d'une Structure
@Eric : Non je persiste et signe sur ma phrase, chaque structure événement gère sa propre file d'attente
"sa ou ses" files d'attentes, et seule la file statique et une propriété intrinsèque de la structure event. (à mon sens)
la doc NI va dans ce sens:
Avoid branching an event registration refnum wire because that allows multiple Event structures to pull events
from one queue and introduces a race condition that can cause unpredictable behavior.
Une pile pour 2 structures ... je pense que mon soucis se trouve là , non ?
Ce que je pense de tout ceci,
Avec des static_event, on a pas à se poser de questions ... LV crée une pile indépendant, d'office, par structure. Jamais de soucis.
Avec des dynamic_event, ce n'est pas la même chose, "on" crée une pile (supplémentaire) en cablant une Reference d'enregistrement
sur un Terminal dynamic. LV gère les event en dépilant la pile statique et la pile dynamique (si il y en a une)
Oui, la pile dynamqiue est liée à la structure mais est intimement liée à l'existence d'un Register_for_Event.
(doc NI) Each Event structure and Register For Events function on the block diagram owns a queue ...
Même NI "semble" se perdre un rien dans la petite nuance.
le 11-12-2013 02:39 AM
Salut Ouadji,
Merci pour tous ces tests, qui permettent de bien comprendre le comportement des structures événements, et principalement des événements dynamiques.
Olivier L. | Certified LabVIEW Developer
le 11-12-2013 09:47 AM
Merci Olivier, c'est sympa.
oui, je fais plein de tests sur les event dynamiques pour le moment.
Je voyais "ça" comme des choses assez obscures ... mais là, je commence réellement à comprendre.
c'est très intéressant ... (voir le sujet dialogue alpha-beta)
Pour le moment, je suis un rien plus loin.
Je lance 2 VIs de façon asynchrones et je les fais dialoguer entre eux. (le "main_lanceur" n'intervient pas)
A intervalles réguliers, chacun des deux demande à l'autre la valeur de son terminal d'itération.
Je fonctionne par question-réponse. Le tout par événements dynamiques.
C'est très amusant d'observer les échanges entre les deux.
le 11-20-2013 06:13 PM
Je suis tombé sur une explication très intéressante de Craig_S
sur les Event dynamiques et le fonctionnement des Piles dynamiques.
Quand on parle d'Event dynamiques, il est clair que les choses fonctionnent d'une autre façon (que pour les event statiques)
Juste un morceau de phrase ... et le reste est tout aussi intéressant.
Now, in order for the system to be able to keep track of events as they happen from the moment they are registered,
the event queue for dynamic events clearly must be associated with the Register for Events node ...
Craig utilise même me terme de "dynamic event queue refnum" ... surprenant !
Ce texte explique réellement les choses de l'intérieure, je trouve ça passionnant !