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 :

cout<< avec plusieurs threads


Sujet :

Threads & Processus C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2017
    Messages : 34
    Points : 14
    Points
    14
    Par défaut cout<< avec plusieurs threads
    Bonjour,
    j'ai fait un programme où plusieurs threads recherchent simultanément la solution d'un problème d'optimatisation , et proposent la leur quand ils en ont une.
    Il arrive parfois que deux threads trouvent en même temps, et là les malins utilisent en même temps l'objet "cout" ce qui donne sur la console un drôle de charabia.
    Comment m'y prendre pour faire un lock sur iostream ?
    Merci

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Ce que j'ai fait il y a fort longtemps:
    - un streambuf frontal qui contient un streambuf par thread (en interne, il peut contenir un buffer de chars sous forme de vecteur p.ex.), et qui contient une référence vers le streambuf qui appartenait initialement au flux sortant final (genre std::cout, ou même un fichier, ça ne change rien)
    - on change le streambuf de std::cout (ou du fichier) par celui de premier niveau
    - quand quelque chose arrive sur le frontal, c'est dispatché au sous-streambuf du thread courant
    - quand un flush arrive, il est dispatché au streambuf du thread courant donc, et cela a pour effet de dispatcher ce qui est couramment en cache dans le streambuf du thread vers le streambuf de destination, avec flush en plus.

    Ca, c'est la solution canonique type, 100% flux. Ce n'est pas forcément la plus pertinente aujourd'hui.

    L'autre solution est d'utiliser une lib dédié et fait ça, et bien plus, comme spdlog p.ex.

    Autre possibilité: avoir un thread de collecte les résultats (avec queue de messages), et c'est ce seul thread qui se charge des logs & cie. C'est probablement le désign le plus commun aujourd'hui j'imagine.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    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 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    J'allais aussi dire "utiliser une bibliothèque de logging" et j'allais aussi proposer spdlog. Je me vois obliger de plusser

    @Legro: L'exemple de base devrait résoudre ton problème : https://github.com/gabime/spdlog#usage-samples

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2017
    Messages : 34
    Points : 14
    Points
    14
    Par défaut
    Merci !

    Autre possibilité: avoir un thread de collecte les résultats (avec queue de messages), et c'est ce seul thread qui se charge des logs & cie. C'est probablement le désign le plus commun aujourd'hui j'imagine.
    Ah ben oui tout bête et tout simple. Je pense que dans mon cas où il ne s'agit que de quelques affichages ci et là, cette solution suffira largement.

  5. #5
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    spdlog est excessivement simple à mettre en place. Bien plus que de dédier un thread aux logs.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre régulier

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2003
    Messages : 120
    Points : 82
    Points
    82
    Billets dans le blog
    1
    Par défaut
    Legro un unique operateur << est garanti thread safe, donc ce que je fait moi c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    std::stringstream msg;
    msg << "Error:" << Err_num << ", " << ErrorString( Err_num ) << "\n"; 
    std::cout << msg.str();
    I'm assuming that what you're really trying to do it stop std::cout from mixing string when concatenating with the operator<< multiple time per string, across multiple threads.
    source : https://stackoverflow.com/questions/...ut-thread-safe
    Ubuntu fan depuis la 8.04
    monnaie libre

  7. #7
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Katian Voir le message
    Legro un unique operateur << est garanti thread safe, donc ce que je fait moi c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    std::stringstream msg;
    msg << "Error:" << Err_num << ", " << ErrorString( Err_num ) << "\n"; 
    std::cout << msg.str();
    Ce n'est pas garanti thread safe dans ce sens-là.

    Dans le cas de std::cout, par défaut, on a bien la garantie qu'un appel à << n'engendre pas de data race, mais pas de garantie que l'opération soit atomique, donc il peut y avoir des intercalations de caractères.

    Extrait de la doc de std::cout :
    « Unless sync_with_stdio(false) has been issued, it is safe to concurrently access these objects from multiple threads for both formatted and unformatted output. »

    Mais voici ce que dit la doc de std::std::ios_base::sync_with_stdio :
    « In addition, synchronized C++ streams are guaranteed to be thread-safe (individual characters output from multiple threads may interleave, but no data races occur) ».

  8. #8
    Membre régulier

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2003
    Messages : 120
    Points : 82
    Points
    82
    Billets dans le blog
    1
    Par défaut
    merci Pyramidev, je pensais avoir trouvé une solution simple, désolé

    A mutex-protected wrapper for cout is probably the best way to go.
    Ubuntu fan depuis la 8.04
    monnaie libre

  9. #9
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Comme solution "simple" à venir il y a std::osyncstream de c++20. Mais actuellement mieux vaut utiliser une bibliothèque externe.

  10. #10
    Membre régulier

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2003
    Messages : 120
    Points : 82
    Points
    82
    Billets dans le blog
    1
    Par défaut
    merci !

    et ce code pourrais faire l'affaire ?

    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
    static std::mutex mtx_cout;
     
    // Asynchronous output
    struct acout
    {
            std::unique_lock<std::mutex> lk;
            acout()
                :
                  lk(std::unique_lock<std::mutex>(mtx_cout))
            {
     
            }
     
            template<typename T>
            acout& operator<<(const T& _t)
            {
                std::cout << _t;
                return *this;
            }
    };
    Ubuntu fan depuis la 8.04
    monnaie libre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. threads et fonction avec plusieurs paramètres
    Par stevelaclasse dans le forum C
    Réponses: 1
    Dernier message: 03/04/2011, 14h02
  2. Script plante avec plusieurs threads
    Par max235 dans le forum Général Python
    Réponses: 2
    Dernier message: 20/04/2009, 15h51
  3. démarrer mysql avec plusieurs threads
    Par nocrack dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 12/10/2007, 16h03
  4. conflits avec plusieurs thread ?
    Par ac/dc dans le forum C++Builder
    Réponses: 4
    Dernier message: 16/04/2007, 20h47
  5. Shortcut avec plusieurs touches
    Par scorpiwolf dans le forum C++Builder
    Réponses: 4
    Dernier message: 06/07/2002, 15h57

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