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

Threads & Processus C++ Discussion :

écrire avec un thread et lire avec un autre


Sujet :

Threads & Processus C++

  1. #21
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    4 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 4 368
    Points : 13 177
    Points
    13 177
    Billets dans le blog
    1
    Par défaut
    C'est possible. Mais j'ai envie de te répondre que ça dépend de l'implémentation de 'queue' et je n'ai pas regardé comment ça fonctionne en interne.

    PS : en regardant sur le net, tu n'as aucune garantie concernant les accès concurrents. Donc perso, je protégerai.....et si je montre un code à un débutant je préfère qu'il soit "trop" robuste que déficient

  2. #22
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 254
    Points : 6 096
    Points
    6 096
    Par défaut
    Bonjour,

    Aucune collection de la STL n'est garantie thread safe. Ça serait une contrainte beaucoup trop lourde. Les seuls objets thread safes sont ceux pour lesquels c'est dit explicitement : à ma connaissance : les atomic, les objets de synchro y compris les promise et le shared_ptr.
    Comment peut-on garantir que deux accès à une queue ne posent pas de problème?
    * Si la queue n'a qu'un élément, il est facile de voir qu'une lecture ou extraction de cet élément ne peut pas cohabiter temporellement avec une insertion que le système soit basé sur un vector, un deque, une list ou une forward_list.
    * Il faut au moins trois éléments pour que les opérations aux extrémités soient gérables indépendamment.
    Même le simple champ size() des collections doit être en temps fixe. Ce qui oblige pour la plupart un donnée incrémentable atomiquement et pour certains processeur cela nécessite un spinlock ce qui a un coût CPU quand même dommageable.

    Un array est lui a priori thread safe, encore faut-il que ses éléments le soient, mais aussi que leur accès ne pose pas de problème. Donc pour cela il faut aussi que leur taille soit un multiple de std::hardware_constructive_interference_size pour qu'une écriture et une lecture par des threads différents soit possible.

  3. #23
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 463
    Points : 29 695
    Points
    29 695
    Par défaut
    Je suis d'accord pour la taille, mais l'implémentation classique de l'insertion ressemble à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void insert(Element * temp){
        // la liste n'est pas vide
        if (back_){
            back_->next = temp;
        }
        back_ = temp;
       // la liste était vide
       if(! top_)
           top_=temp;
        ++size_;
    }
    et l'implémentation classique pour la suppression ressemble à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void pop(){
        assert(top_)
        Element * temp = top_->next;
        delete top_;
        top_ = temp;
       // c'était le dernier élément
       if(!top_)
         back_=nullptr;
       --size_;
    }
    On a donc plusieurs situations possibles:
    1. insérer le premier élément
    2. insérer un deuxième élément
    3. insérer un N ieme élément (où N > 2)
    4. supprimer l'unique élément de la liste
    5. l'implémentation de la file est basée sur l'utilisation d'une autre structure dynamique.


    (1) A partir du moment où le thread B teste [/c]!empty()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     avant de faire quoi que ce soit, le thread A n'a aucune chance de se faire "voler la vedette" par B lors de l'insertion.
     
    (3)Aucun problème apparent : thread a manipule back_, thread B manipule top_. Reste le problème de size_ qui n'est pas atomic; mais que l'on fasse ++size_; --size_ (thread A, thread B) ou --size_; ++size_; (thread B, thread A) ne devrait pas changer grand chose
     
    (4) Aucun problème à partir du moment ou le thread B teste
    !empty()[c] avant de faire quoi que ce soit : le thread B n'essayera de retirer un élément que si le thread A a terminé de l'y insérer

    (5) Ah, oui, là... tout peut arriver

    Finalement, sur une implémentation classique de la file (donc, si on a la certitude qu'elle n'est pas implémentée sous la forme d'une autre structure dynamique) qu'un seul cas "peau de bannane" : si le thread A essaye d'ajouter ce qu'il considère être comme le deuxième élément de la liste alors que le thread B essaye de supprimer ce qu'il considère être comme le seul élément de la liste.

    Mais, dés lors, pourquoi ne pas se contenter de verrouiller la liste que dans ce cas particulier

    Bien sur, il se peut que j'aie loupé quelque chose... n'hésitez pas à me reprendre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #24
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    6 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 6 675
    Points : 30 458
    Points
    30 458
    Billets dans le blog
    4
    Par défaut
    Tu peux te passer de lock si et seulement si ton implémentation de queue a des fonctions push & pop atomiques.
    Mais ceci n'est pas du tout le cas de la std, où queue n'est qu'une surcouche autour d'un autre container, et où push n'est qu'un appel à push_back sur ce container, et pop un appel à pop_front.
    Malgré l'insertion et retrait des éléments aux extrémités et l'accès à n'importe quel élément en temps constant du container par défaut std::deque, ces opérations ne sont pas pour autant atomiques.
    Donc le lock est ici obligatoire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #25
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 463
    Points : 29 695
    Points
    29 695
    Par défaut
    Oui, de fait...

    Et, de plus, je me suis intéressé à l'implémentation de std::queue fournie par Gcc-7, et elle se base sur celle de std::deque par défaut.

    Or, la gestion de std::deque n'a absolument rien d'atomique

    Mettons donc que je n'ai rien dit
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Lire avec fscanf dans un fichier avec délimiteurs
    Par Share45 dans le forum Débuter
    Réponses: 14
    Dernier message: 04/02/2016, 18h58
  2. Problème avec 2 threads : l'un bloque l'autre
    Par pontus21 dans le forum Linux
    Réponses: 13
    Dernier message: 17/01/2008, 13h09
  3. Des problemes avec ces threads <pthread.h>
    Par nasamad dans le forum GTK+ avec C & C++
    Réponses: 26
    Dernier message: 07/07/2006, 12h46
  4. [Threads] Actions continues avec des threads
    Par MiJack dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 10/10/2005, 17h32
  5. [langage] Perl a t'il été compiler avec les threads
    Par vodevil dans le forum Langage
    Réponses: 2
    Dernier message: 07/05/2005, 15h00

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