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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 753
    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 753
    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 397
    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 397
    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 753
    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 753
    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

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 753
    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 753
    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

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 753
    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 753
    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

  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).

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