IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Question pour les maitres du multithreading


Sujet :

Windows

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut Question pour les maitres du multithreading
    Apres avoir lu le tuto sur les API windows de bob, je me suis dit, "boaaa le multithread ca n'a pas l'air si compliqué que ca !!!" lol appriori du débutant en couche culotte.
    J'ai quelques questions assez pointues qui s'adressent aux maitres dans l'art du multithreading, je vais essayer d'etre aussi concit et précis que possible, j'espere que ce topic ne découragera personne, j'ai vraiment besoin de comprendre. (vous donnez des cours?)

    Je developpe en C++ sous visual 2003 mon appli est dédiée a des pc 32 ou 64bits sous XP Pro.

    Situation : J'ai 2 thread A et B les 2 s'executent régulierement (cycliquement on pourait dire), et on ne peut pas savoir si A est lancé avant B ou l'inverse ou en "meme temps". Donc on ne peut encore moins savoir si une instruction foncA dans ThreadA est executée avant, ou apres foncB dans ThreadB.
    Thread A ecris sur une variable toto, Thread B lit cette variable. Voici mon probleme à résoudre, je veux que quand threadA change l'etat de toto, ThreadB soit capable de lire le nouvel etat de toto et non son etat précédent ou suivant. Je rappelle que threadA s'execute cycliquement, lors de sa prochainne passe il pourra de nouveau modifier la valeur de toto, et il faut a tout prix que ThreadB catch toutes les valeurs que toto peut prendre.
    Concretement ThreadA incremente à chaque passe toto et il faut absolument que thread B sur chacune de ses passe puisse lire toto==1 toto==2 toto==3 et non toto ==1 toto ==3 (toto==2 etant passé à la trappe).

    Hypothese le cpu est réparti de la facon suivante :
    30ms pour thread A
    30ms pour thread B
    100ms pour le kernel
    et ca tourne en boucle

    Contenu thread A :
    foncLambda1()
    toto=1
    foncLambda2()

    Contenu thread B
    foncLambda1()
    if(toto==1)
    foncLambda2()

    Sur une passe multithread, le hasard fait que :
    execution / ThreadA::toto=1
    threadA rend la main
    threadB prend la main
    execution / ThreadB::f(toto==1)
    ...

    Voici enfin mes questions hyper pointue :
    Question 1) est il possible que toto n'ai pas encore eu le temps de passer à 1 et que ThreadB lise un toto==0 ?
    Question 2) est il possible pour des question d'optimisation, je pense particulierement à un proc 64bits traitant 2 infos 32bits sur un meme cycle d'horloge que l'on ait un truc du genre:
    ThreadA::toto=1,ThreadB if(toto==1);
    ou
    ThreadB if(toto==1),ThreadA::toto=1; ??
    Question3) quelle methode me conseilleriez vous pour etre sur que ThreadB lise toujours la bonne valeur de toto sans louper un cycle de ThreadA parcequ'il se met en attente?

    J'ai plein d'autres questions sur le sujet, mais deja ca, c'est pas mal

  2. #2
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Bonjour,

    Après une lecture interessé du sujet, j'aurais une suggestion, malheureusement je ne suis pas expert en multithread, donc il faudra surement que tu attendes un "guru" pour avoir une réponse purement technique, mais j'ai quand même un truc à dire :

    - Imaginons que ton threadB "attende un evenement" déclenché par la mise à jour de toto dans threadA. Du coup, ton problème serait "résolu". threadA déclencherait cet evenement, qui permettrait à threadB de faire son traitement
    - Suite à ça, une autre question se pose dans ma petite tête de linotte savante(lol) : pourquoi un threadB ? Etant donné que ton threadB a l'air d'être une execution "paramétrée", je ne vois pas en quoi une parallélisation des traitements se justifie dès le départ; une thread pourrait être crée à chaque fois que threadA incrémente toto, afin de traiter ce toto particulier; peut-être que le fonctionnement de ton application impose le schéma que tu as décris ?
    - Dernière petite chose qui me turlupine : dans quel cas penses-tu que threadB pourrait lire toto==0 ? toto est surement indéfini à un instant T, ne serait-ce qu'au démarrage de ton application par exemple ? ça risque de poser un problème non ? moi po comprendre...

    A+
    K

  3. #3
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Il ne faut pas te soucier de qui est exécuté quand et comment. Si tes thread partagent des données, il y a besoin de synchronisation. Y'a tout un tas de solutions, et ton problème est un cas d'école (lecteur / écrivain). Avec un mécanisme de synchro type mutex (= verrou), le thread A sera bloqué avant chaque nouvelle modification de toto tant que B n'aura pas lu toto et débloqué le mutex.

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Le probleme, c'est que je ne peux pas utiliser ce systeme de mutex.
    Mon thread A est en priorité TimeCritical, il attends un etat matériel et retourne l'info aux autres threads puis se met en sommeil en attendant qu'on le reveil de nouveau. entre l'instant où l'evenement matériel a lieu et quand le thread retourne l'info, j'ai 5 ms pour agir, maximum ! actuellement j'arrive a le faire en 2 ms.

    Si j'emploi un mutex via thread B, je réduit en un sens la priorité du thread A a celle du thread B, les 5ms ne seront plus respectées

    Je peux reveiller thread A trop tard, mais quand il est lancé je ne peux plus l'arretter pour respecter le delai imposé. Quand a thread B il s'agit en fait du thread principale de l'appli MFC et sa partie interressée est une callback qui doit toujours savoir si elle doit traiter l'evenement grace à thread A.

    En bref, Thread B peut louper une raffale d'evenement (parceque thread A dort), mais en aucun cas manquer un evenement à traiter dans une raffale d'evenement.

    Alors vous allez surement me dire, pourquoi ne pas mettre tout le traitement dans thread A. Et bien parceque la callback dans thread B (le thread de l'appli MFC) est accroché à un evevenement d'un activeX qui est dans une boite de dialogue. Je n'ai pas le choix, c'est le SDK qui m'est fourni qui m'impose ca.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Dans ton cas avec les rafales d'événements, je conseillerais de rassembler tous ces événements dans le thread A, pour les envoyer au thread B lorsque le dernier est reçu.

    Et pour prévenir ainsi le thread B, pourquoi ne pas utiliser simplement PostMessage() ou PostThreadMessage() ?

    Ou bien, tu as aussi les events, qui peuvent peut-être remplacer avantageusement les mutexes dans ton cas...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Mon thread A ne peut detecter que le premier ellement d'une raffale (c'est obligatoirement une raffale de 2 evenements, et 2 raffalles ne peuvent pas se chevaucher (ouf) ).

    Quand Aurelien a parlé de mutex, j'ai immediatement pensé aux event (chose que j'emploi deja pour mettre thread A en someil).

    En fait je pense que je vais utiliser cet histoire de mutex, mais dans l'autre sens :

    plutot que Thread A attende que Thread B ai lu l'info. Thread B va attendre que Thread A ai finit d'ecrire le tout via des events Je pense qu'ainsi (vu la rapidité du thread A par rapport au thread B) je respecterai mes conditions....

    En gros ca donne un:

    Thread A:
    ResetEvent(BlockB);
    toto = 1;
    SetEvent(BlockB);

    Thread B:
    WaitForSingleObject(BlockB);
    if(toto==1);

    L'histoire des postmessage, ca ne me plait pas, ca passe par une pile de message, on ne sait pas quand c'est recu. Pour mon histoire de Thread A, toto est mis à jour "plus vite que la musique".

  7. #7
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    pourquoi ne pas ouvrir un thread à chaque reception d'evenement ?
    K

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    parceque c'est completement assynchrone avec l'evenement matériel lu par thread A. Justement Thread A dit "heey thread B : le prochaine evenement que tu recevera je ne sais quand... c'est le bon, fonce !!!"

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    KilVaiden : Parce que ça prendrait un temps fou à créer, et il semblerait qu'on n'ait pas le temps.

    giova_fr, le problème principal est que le thread A peut recevoir une nouvelle donnée et modifier la variable toto avant que le thread b l'ait lu...

    Sinon, tu peux peut-être utiliser SendMessage() : c'est prioritaire sur PostMessage(), et le thread B peut utiliser ReplyMessage() pour libérer le thread A avant la fin du traitement.

    Ainsi, le thread B pourrait recevoir le messase, lire la valeur, appeler ReplyMessage(), (à ce moment-là, le thread A repart) puis traiter tranquillement ses valeurs.

    Mais dans tous les cas, il vaut que la donnée soit entièrement traitée avant qu'une nouvelle donnée arrive. Sinon, on utilise une file d'attente...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Ok oui, ça prendrait du temps de créer une thread à chaque étape, mais le temps de réponse est-il crucial dans "la reception de l'évènement (threadA)" ou dans "le traitement de celui-ci (threadB)" ?

    J'ai une idée à soumettre, vous me direz ce que vous en pensez : introduire un threadC, qui aurait une "queue" d'evènement à traiter par threadB. Ainsi, threadA déposerait un evenement à chaque fois dans la queue, et quand threadB est dispo, il peut traiter les éléments de la queue, dans l'ordre. Est-ce que ça conviendrait ?
    K

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ben, c'est ce qu'on peut faire avec seulement les threads A et B et la fonction PostMessage(), mais giova_fr a déjà rejeté cette proposition...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Citation Envoyé par Médinoc
    Ben, c'est ce qu'on peut faire avec seulement les threads A et B et la fonction PostMessage(), mais giova_fr a déjà rejeté cette proposition...
    Désolé si j'ai mal compris le problème

    Je pense que c'est assez différent quand même, car l'introduction d'un 3ème thread se chargeant uniquement de gérer la communication asynchrone entre A et B permettrait de conserver le threadA et le threadB "indépendant" les uns des autres, threadA pourrait déposer des evenements aussi vite qu'il le souhaite, et threadB peut les dépiler aussi vite qu'il le souhaite également. Enfin, je vais arrêter de parler d'un domaine que je ne connais pas trop désolé
    K

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ben, ça fait pareil avec la fonction PostMessage() (ou PostThreadMessage()) de Windows: Le thread les reçoit quand il a du temps à leur accorder...
    (La boucle de message d'un thread d'interface passe la majeure partie de son temps à attendre sur la fonction GetMessage())
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Pour améliorer les performances, tu peux utiliser un buffer circulaire pour ne pas bloquer a chaque écriture / lecture.
    Le thread A remplit le buffer avec les données reçues, le thread B le vide. Typiquement, c'est un tableau de 100 éléments par exemple, avec un indice de début et un indice de fin. Le thread A ajoute des données en incrémentant l'indice de fin, le thread B lit les données en incrémentant l'indice de début. Quand l'un ou l'autre arrive à 99 on repart à 0 (circulaire). Si le buffer est plein (debut = (fin + 1) % Taille), ben à priori le thread A reste bloqué. Tu n'as pas trop le choix, ou alors tu décides de perdre des données.
    Si le buffer est vide, les thread B doit rester bloqué tant qu'il n'y a pas de nouvelles données. Cela peut être fait via un event que A signale quand il a écrit une donnée. B attend l'event, et il consomme alors tout ce qu'il peut, et A n'est pas bloqué après une écriture.
    Je ne crois pas qu'il y ait besoin de contrôle l'accès concurrent aux indices debut et fin.

  15. #15
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Après lecture du post d'Aurelien.Regat-Barrel, je repense à l'idée de rajouter un threadC. L'avantage est que si pour une raison X ou Y le threadA venait à mourir, le threadB et le threadC pourraient continuer à travailler avec les données restantes dans ce qu'Aurélien appelle le buffer
    K

  16. #16
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Tres interressant tout ca, l'idée du buffer me plait bien, ca revient en un sens à réinventer un systeme de messages windows mais on a totalement la main dessus, c'est pas mal du tout, surtout que vu la rapidité du thread A (environ 5ms en priorité timecritical avant de repasser en someil) ca me permetrait de faire quelquechose de rapide et à mémoire. En plus je pourrais grace à cela detecter des pertes d'evenement. J'achete !!!

    Merci à tous, maintenant, y a plus qu'à

    Je vous tiendrai au courrant de mes découvertes... (vu le temps imposé à savoir demain soir la deadline, je vais faire sans buffer, mais je sais que je vais tres tres prochainement devoir y venir. En effet Thread A regarde une broche d'une carte I/O (relié à un boitier trigger); demain il devra regarder toutes les broches)

  17. #17
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Pfff.... quelle horreur, ca des raffales, j'en ai, des raffalles de pertes d'evenements

    Bon, ca ne marche pas du tout mon histoire, c'est meme pire que quand je ne synchronisait pas mes threads, maintenant, mes mutex créent un effet en cascade, mon evenement du thread B prend a chaque passe un peu plus de retard de facon tres réguliere, puis evidemment ca finit par décrocher

    Et a debugger c'est quasi impossible (heurement que je peux gerer des io et regarder ca à l'oscillo)

    Et puis j'ai réalisé une chose (qu'importe que le mutex soit dans le lecteur ou l'écrivain):

    Voici un exemple de cas foireux:

    //threadLecteur:
    SetEvent(blabla);
    toto=1;
    ResetEvent(blabla);

    //ThreadEcriveur:
    WaitForSingleObjet(blabla);
    //Ici le thread perd la main. AH AH !!!
    if(toto==1);

    Comment se défendre face à une telle situation?

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ben, tu peux pas tellement... C'est pas facile d'éliminer ce genre de "race condition"...
    Je ne vois pas vraiment de solution à part faire (ou utiliser) une vraie file d'attente...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Je suppose que tu as inversé threadLecteur <-> ThreadEcriveur.
    threadLecteur (ton exemple) ne doit pas faire de ResetEvent, ça sert à rien, tu annules ton précédent SetEvent. Là tu mélanges avec un Mutex.
    Et dans ce context, il faudrait plutôt utiliser une section critique (+ performant).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //ThreadEcriveur&#58;  
    toto=1; // modifier toto
    SetEvent&#40;blabla&#41;; // signaler qu'il a été modifié
    
    //threadLecteur&#58; 
    WaitForSingleObjet&#40;blabla&#41;; // attendre une modif, le ResetEvent est implicite si créé correctement
    copie_toto = toto; // lire toto
    et effectivement tu peux avoir un problème lors de la lecture de toto, mais c'est un 2° problème, qui se résoud via une section critique par exemple, ou si tu ne veux rien perdre, par un 2° event qui bloque ThreadEcriveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //ThreadEcriveur&#58;  
    toto=1; // modifier toto
    SetEvent&#40;modif&#41;; // signaler qu'il a été modifié
    WaitForSingleObject&#40;lu&#41;; // attendre qu'il soit lu
    
    //threadLecteur&#58; 
    WaitForSingleObject&#40;modif&#41;; // attendre une modif
    copie_toto = toto; // lire toto
    SetEvent&#40;lu&#41;; // signaler qu'on a lu
    mais vu ainsi on se demande l'utilité du multithread. Faudrait gérer un buffer
    Note aussi que la combinaison SetEvent + WaitForSingleObject peut se remplacer par SignalObjectAndWait.

  20. #20
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Merci mille fois pour vos eclaircissement, Aurelien, je vais etudier tout ce que tu as ecris, mais j'ai peur de ne pas trop comprendre pour la critical section, a ma connaissance, elle force un bout de code a etre "exclusif" si plusieurs instances du thread sont en cours...

    Or dans mon cas j'ai un (en ignorant la partie mutex foireuse pour alleger le code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //ThreadA &#40;priorité RealTime&#41;
    
    SetEvent&#40;ReveilThreadA&#41;;
    
    while&#40;&#40;bool&#41;cmdThreadA&#41;
    &#123;
         WaitForSingleObject&#40;ReveilThreadA&#41;;
         //Ici je dois etre ultra rapide, ca ne dure pas longtemps
         &#91;...&#93;
         toto=1;
         //A la rigueur ici je pourrai repasser en priorité moyenne
         // Je veux dire je pourrai envisager un WaitForSingleObject&#40;lu&#41;
         ResetEvent&#40;ReveilThreadA&#41;;
    &#125;
    //ThreadB

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CALLBACK routine&#40;&#41;
    &#123;
       if&#40;toto==1&#41; //Ah thread A me dit qu'il faut se mettre au boulot
       &#123;
           &#91;...&#93;
           SetEvent&#40;ReveilThreadA&#41;; //Boulot terminé je rends la main
       &#125;
    &#125;
    Ecris comme ca, ca semble foireux car toto pourrait toujours etre à 1 lors de la prochaine passe sur routine() c'est là qu'est tout mon dilem

Discussions similaires

  1. Question pour les experts
    Par Philippe66 dans le forum HyperFileSQL
    Réponses: 1
    Dernier message: 31/08/2006, 23h35
  2. Questions pour les encodages
    Par alfa88 dans le forum Autres Logiciels
    Réponses: 6
    Dernier message: 20/05/2006, 20h32
  3. [ HIBERNATE ] Question pour les doués
    Par Néo-Tony dans le forum Hibernate
    Réponses: 25
    Dernier message: 23/02/2006, 15h23
  4. Réponses: 3
    Dernier message: 14/12/2005, 23h08
  5. Questions pour les developpeurs independants
    Par voyageur dans le forum Freelance
    Réponses: 5
    Dernier message: 22/06/2005, 11h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo