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

C++ Discussion :

équivalent du pthread_cond_wait de POSIX (unix) en visual C++


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut équivalent du pthread_cond_wait de POSIX (unix) en visual C++
    Bonjour,

    Je code un programme sous visual studio avec un thread producteur et un thread consommateur, en passant par une FIFO.
    Je voudrais que le consommateur s'endorme quand il voit qu'il n'y a plus rien a faire et que le producteur le réveille quand il rajoute du travail dans la FIFO.

    J'ai donc besoin de fonctions équivalentes aux pthread_cond_wait et pthread_cond_signal de POSIX thread (unix) sous visual C++ (j'utilise les threads de System.Threading), mais je n'en ai pas trouvé dans msdn (à part suspend et resume, mais msdn dit qu'ils sont obsolètes et qu'ils vont être supprimés).

    Est ce que quelqu'un connaitrait des fonctions pareilles?

    Merci d'avance!

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut un semaphore
    Avec les primitives WaitForSingleObject et ReleaseSemaphore me semblerait plus approprié.
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    Oui, je suis d'accord que finalement, les sémaphores conviendraient mieux, pour une question d'atomicité.
    Voici le code de ma FIFO:
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    template<typename T>
    ref class queue_en_mutex 
    {
    private:
    	Mutex^ mutex_de_queue;
     
    public:
    	std::queue<T> * queue_std;  // car on peut avoir un pointeur vers un objet non managé mais pas un objet non managé dans une classe managé?
     
    	queue_en_mutex(){
    		queue_std = new std::queue<T>;
    		mutex_de_queue = gcnew Mutex;
    	};
    	~queue_en_mutex(){};
     
        T pop(){
            T res;
            mutex_de_queue->WaitOne();
            res = queue_std->front();
            queue_std->pop();
            mutex_de_queue->ReleaseMutex();
            return res;
        };
     
        void push(T t){
            mutex_de_queue->WaitOne();
            queue_std->push(t);
            mutex_de_queue->ReleaseMutex();
        };
     
    	bool empty(){
    		bool res;
    		mutex_de_queue->WaitOne();
            res = queue_std->empty();
            mutex_de_queue->ReleaseMutex();
    		return res;
    	}
     
    };
    Le problème est que le consommateur va faire un empty(), puis un pop(), mais que les deux appels ne formeront pas une instruction atomique. Un scenario "pas de chance" serait donc:
    _le consommateur fait un test pour voir si la FIFO est vide avec empty(), qui lui dit qu'elle est vide.
    _le producteur ajoute un élément à la FIFO et réveil le consommateur, qui ne s'est pas encore endormi.
    _le consommateur s'endort et attend un signal, qui est déjà passé et qui n'arrivera donc jamais.

    Je pense que je vais donc plutot utiliser un sémaphore. On fait un release du sémaphore après un push, et un waitone avant le pop. Le consommateur saura qu'il a terminé quand il tombera sur un élément spécial (ex: "travail_terminé") dans la queue.

    Cependant, j'ai l'impression que les sémaphores de visual C++ ont forcément une valeur maximum. Est ce que quelqu'un connaitrait un moyen de ne pas avoir de valeur maximun, svp?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Normalement, pour du producteur/consommateur, il faut DEUX sémaphores: Un pour compter les places pleines, un pour compter les places vides.

    Quant à leur valeur maximale maximale, je serais étonné qu'elle soit inférieure à INT_MAX...
    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.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    J'utilise une queue, dans laquelle mon thread producteur met tous les événements que lui envoie flight simulator (il y en a beaucoup par seconde). le thread consommateur analyse ces évènements, ce qui peut prendre du temps. La queue va donc devenir de plus en plus longue, d'autant plus que l'expérience pendant laquelle on récupère les événements peut durer longtemps. La queue n'est pas limitée en taille.

    Utiliser INT_MAX donne une certaine sécurité, mais ce serait quand même mieux si il n'y avait pas de borne supérieure. en plus, je serai forcé d'utiliser un deuxième sémaphore pour compter les places restantes et éviter le SemaphoreFullException, ce qui va ralentir un peu plus mon thread . D'autre part, si le sémaphore est stoqué dans un int et qu'il n'y a rien de prévu pour le cas où il y ait un overflow, il ne doit pas y avoir de solution.

    Personne ne saurait si on peut utiliser ce sémaphore sans borne supérieur?

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut Le mutex ne sert qu'à sérialiser l'accès aux sections critiques.
    Lorsque:

    Le problème est que le consommateur va faire un empty(), puis un pop(), mais que les deux appels ne formeront pas une instruction atomique. Un scenario "pas de chance" serait donc:
    1. _le consommateur fait un test pour voir si la FIFO est vide avec empty(), qui lui dit qu'elle est vide.
    2. _le producteur ajoute un élément à la FIFO et réveil le consommateur, qui ne s'est pas encore endormi.
    3. _le consommateur s'endort et attend un signal, qui est déjà passé et qui n'arrivera donc jamais.
    Je ne vois pas trop comment 2, va pouvoir signaler quoique ce soit au consommateur. Il viendra pooler un peut plus tard la FIFO pour s'apercevoir qu'elle n'est plus vide et faire des pop.
    En 3, le signal qu'attend le consommateur est peut être la fin du sleep pour recommencer le test.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Normalement, pour du producteur/consommateur, il faut DEUX sémaphores: Un pour compter les places pleines, un pour compter les places vides.

    Quant à leur valeur maximale maximale, je serais étonné qu'elle soit inférieure à INT_MAX...
    N'est-ce pas dans le cas ou le nombre de place libre est borné?
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    J'utilise une queue, dans laquelle mon thread producteur met tous les événements que lui envoie flight simulator (il y en a beaucoup par seconde). le thread consommateur analyse ces évènements, ce qui peut prendre du temps. La queue va donc devenir de plus en plus longue, d'autant plus que l'expérience pendant laquelle on récupère les événements peut durer longtemps. La queue n'est pas limitée en taille.
    Vous aurez toujours besoin d'un mutex pour gérer la synchronisation d'accès aux variables.
    Le sémaphore pourrait venir par dessus pour compter le nombre d'évènements à traiter: lorsqu'il n'y en a pas, le consommateur attend.

    Utiliser INT_MAX donne une certaine sécurité, mais ce serait quand même mieux si il n'y avait pas de borne supérieure. en plus, je serai forcé d'utiliser un deuxième sémaphore pour compter les places restantes et éviter le SemaphoreFullException, ce qui va ralentir un peu plus mon thread . D'autre part, si le sémaphore est stoqué dans un int et qu'il n'y a rien de prévu pour le cas où il y ait un overflow, il ne doit pas y avoir de solution.
    Si la valeur du sémaphore compte le nombre d'évènements à traiter, vous aurez des soucis de mémoire physique disponible bien avant d'avoir un overflow... et si vous avez une pile d'évènements si importante, il va falloir tellement de temps pour dépiler tout ca que le joueur sera tenté de rebooter

    Puisque vous savez qu'il y aura rapidement des évènements à traiter, la vraie question est de savoir s'il est utile de mettre un sémaphore plutôt qu'un mécanisme de pooling de l'état de la queue lorsqu'elle est vide...
    => personnellement, maintenant que je comprend mieux votre soucis ce serait peut être ce que j'essaierai en encapsulant la mécanique d'une facon ou d'une autre au cas ou il serait utile d'en changer.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    @ wiztricks: à propos de ton avant dernier post:
    dans la citation de moi que tu as utilisé, je parlais du cas où je n'utilise pas de sémaphore, mais des fonctions qui agissent comme pthread_cond_wait (qui endort le thread) de POSIX thread et pthread_cond_signal (qui réveil un thread qui a fait un pthread_cond_wait).
    Le consommateur aurait donc fait un pthread_cond_wait en voyant la FIFO vide (à l'étape 3), et le producteur aurait fait un pthread_cond_signal (mais trop tôt, à l'étape 2).

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Hmm, ce qu'on attend ou qu'on signale, c'est la condition "file non vide".
    Je ne comprends pas pourquoi il serait "fugace".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Si tu utilises une file d'évenements, pourquoi ne pas utiliser celle mise gracieusement à ta disposition par Windows ?

    PostThreadMessage(), GetMessage()... Tu n'est pas obligé d'ouvrir une fenêtre pour ça...
    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 confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    @ wiztricks:
    Puisque vous savez qu'il y aura rapidement des évènements à traiter, la vraie question est de savoir s'il est utile de mettre un sémaphore plutôt qu'un mécanisme de pooling de l'état de la queue lorsqu'elle est vide...
    => personnellement, maintenant que je comprend mieux votre soucis ce serait peut être ce que j'essaierai en encapsulant la mécanique d'une facon ou d'une autre au cas ou il serait utile d'en changer.
    Il y a beaucoup de technique de "pooling", d'après internet. Tu parles de laquelle? Du fait d'avoir une réserve d'objets à utiliser plutôt que de les créer et les détruires à chaque fois?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Je pense qu'il parlait de polling et non pas de pooling.

    Sous Windows, je peux confirmer qu'un sémaphore "nombre d'éléments dans la file" est plus rapide, puisqu'un thread reçoit un boost de priorité au moment où il est réveillé par un objet de synchronisation...
    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
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    @ Médinoc: ok pour le polling.
    A propos des sémaphores, est ce que tu les utiliserais, même si il y a une borne supérieure qui n'a pas lieu d'être (puisque la queue n'a pas une taille limite), sachant que cette limite est INT_MAX et que si elle est atteinte, il tellement d'événements que le processus mettra une éternité à terminer de les traiter?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    En fait, s'il est garanti que le consommateur ne pourra jamais tout traiter en temps réel, je n'utiliserais même plus une file, ni un buffer bloquant (le coup des deux sémaphores): Je dumperais carrément tout dans un fichier pour le traiter plus tard (typiquement pendant la nuit)...
    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.

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    oui, c'est vrai que c'est plus sur.

    Cependant, j'espere que l'appli ne sera pas trop lourde et qu'elle pourra traiter les evenements en temps réel avant de passer des messages, par exemple "attention, vous n'avez pas sorti les trains d'atterissage!".
    Dans ce cas, tu utiliserais les sémaphores, même si il y a une borne supérieure qui n'a pas lieu d'être (puisque la queue n'a pas une taille limite), sachant que cette limite est INT_MAX et que si elle est atteinte, il tellement d'événements que le processus mettra une éternité à terminer de les traiter?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Le problème majeur quand une file est pleine, c'est que c'est le thread producteur qui se retrouve bloqué (il attend que le consommateur libère une place).

    De plus, je pense que le vrai facteur limitant ne sera pas la valeur limite du sémaphore, mais la taille mémoire disponible (à moins que tu sois en 64 bits)...
    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.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 79
    Par défaut
    Tu veux dire que ma queue (j'utilise la queue de std, qui n'est jamais pleine) sera pleine car je n'aurai plus de place mémoire dans mon processus?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Oui.
    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.

  20. #20
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En fait, s'il est garanti que le consommateur ne pourra jamais tout traiter en temps réel, je n'utiliserais même plus une file, ni un buffer bloquant (le coup des deux sémaphores): Je dumperais carrément tout dans un fichier pour le traiter plus tard (typiquement pendant la nuit)...
    Cela n'améliorera pas les performances
    Ce qu'il faudrait peut être étudier dans ce cas, c'est:
    1. augmenter le nombre de consommateurs,
    2. compacter les événements

    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 5
    Dernier message: 04/02/2007, 11h15
  2. Compiler un projet d'Unix avec Visual .NET
    Par Captain_JS dans le forum MFC
    Réponses: 1
    Dernier message: 05/02/2006, 23h12
  3. Norme POSIX sous Windows et Unix
    Par Franck.H dans le forum Langages de programmation
    Réponses: 9
    Dernier message: 10/10/2005, 20h46
  4. [Fichier] Api équivalent du tail -f sous unix
    Par Actarus78 dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 09/09/2005, 11h34

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