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 :

Débloquer une lecture sur cin en multithread


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut Débloquer une lecture sur cin en multithread
    Bonjour
    Je travaille actuellement sur une grosse appli serveur compilée en gcc/mingw avec les libs boost.

    Cette appli peut se terminer sur une saisie utilisateur (mode console, pas de gui) , ou pour d'autres raison (erreur, reception d'un commande, etc).

    En essayant d'implémenter cela, je m'aperçois que si un thread fait un appel a "exit()" pendant qu'un autre bloque en lecture sur cin, le programme ne se termine pas.

    Voici un exemple de code simple qui provoque cette erreur :
    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
    class Input : public Thread {
    public:
        Input() : Thread() {
        }
     
        virtual void threadMain() {
            sleep(1000);
            std::cout << "thread calls exit" << std::endl;
            exit(0);
            std::cout << "exit done";
        }
     
    };
     
    int main ( int argc, char* argv[] ) {
        Input input;
        input.run();
        std::string i;
        std::cin >> i;
     
        std::cout << "ok, main unlocked with '"<<i << "'" << std::endl;
        return 0;
    }
    aussi étonnant que ca puisse paraitre, ca affiche bien "thread calls exit" au bout d'une seconde, mais il faut valider une entrée clavier pour avoir la terminaison effective du programme, et ca, ca me gène beaucoup.

    J'ai essayé de débloquer cin avec des trucs de type putback, sync, en allant chercher le rdbuf, mais rien n'y fait, toutes ces méthodes sont bloquantes si un thread est en attente de lecture.

    Et il ne parait pas du tout pertinent de passer en lecture non bloquante, ca serait une hérésie, donc pas de kbhit ou autre test...

    Une demi réponse me suffirait : faire marcher le "exit" ou débloquer le cin

    Merci pour vos idées!

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 107
    Par défaut
    je ne sais pas quelle librairie tu utilises mais un thread ne se termine pas normalement avec un exit ; cet appel arrêtant tout le programme.

    De plus l'utilisation de threads dans un programme force la mise en place d'outils de synchronisation entre les threads, chose que tu ne sembles pas faire (e.g. ton thread principal, celui qui instancie la variable i, devrait attendre la fin du thread généré par l'objet input avant de s'arrêter).

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 107
    Par défaut
    Désolé j'ai peut être dégainé un peu vite :-).

    Donc ce que je ferais :
    - pas de exit dans un thread : pas propre ; j'utiliserai tout simplement une condition d'arrêt (e.g. une variable globale, avec mutex si nécessaire)
    - un join_all dans le thread principal afin d'attendre la fin de tous les threads (permet la libération mémoire, les écritures disques, etc)
    - utilisation d'I/O non bloquante (e.g. utilisation d'un select avec timeout pour récupérer une saisie clavier) à cause des threads boost non interruptibles (rhaaa)

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut
    Citation Envoyé par lemmel Voir le message
    - pas de exit dans un thread : pas propre ; j'utiliserai tout simplement une condition d'arrêt (e.g. une variable globale, avec mutex si nécessaire)
    - un join_all dans le thread principal afin d'attendre la fin de tous les threads (permet la libération mémoire, les écritures disques, etc)
    Le petit bout de code au dessus n'est qu'un exemple pour me faire comprendre
    Je fais tout ca en réalité, mais j'ai "isolé" le problème me concernant, à peu de chose pret.

    En l'occurence, pour m'arrêter, n'importe quel thread de l'appli ouvre un monitor sur lequel thread principal est bloqué, et après ce monitor, le thread principal arrête/join/delete etc.

    Parmis ces thread, y'en a par exemple un qui écoute les frappes clavier. Si c'est celui la qui notifie l'arrêt, y'a pas de soucis, mais si c'est par exemple une commande qui est reçue par l'appli, c'est un autre thread qui va notifier l'arrêt, et l'exit marche pas.

    Bref, c'est la troisième remarque qui m'interesse.
    Thread boost non interruptible? Qu'entends tu par la?
    Pour le select, effectivement, ca me parait une bonne idée, je vais creuser, si tu as un bout d ecode sous la main, je suis preneur.

    En tout cas, merci d'avoir pris le temps

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 107
    Par défaut
    Thread boost non interruptible? Qu'entends tu par la?
    en fait, dans les lib systèmes tu peux trouver les appels suivants :
    - sous Unix : plusieurs solutions :
    * il est possible d'envoyer un signal à un thread spécifique, ce qui a pour conséquence d'arrêter tout appel système interruptible (en bref la plus grande partie de ceux-ci ; il n'y a qu'à regarder le code de retour de l'appel système pour savoir si c'est un signal qui a causé le retour) : pthread_kill ; un select est interruptible
    * on peut également appeler pthread_cancel
    Rq : on désigne souvent les appels bloquants comme des points d'"annulation", e.g. cf http://www.gnu.org/software/libc/man...ng-Connections (recherche "cancellation point")
    - sous windows : il est possible d'utiliser TerminateThread (je n'ai guère utilisé de manière avancée les threads sous windows, la doc de cette fonction fait quelque peu peur, mais je suppose quand faisant bien son travail, variable d'exclusion[1] avant de poursuivre le travail après avoir franchir un "cancellation point", et en ne l'utilisant que pour arrêter le programme, que cela doit bien fonctionner


    Pour le select, effectivement, ca me parait une bonne idée, je vais creuser, si tu as un bout d ecode sous la main, je suis preneur.
    http://www.gnu.org/software/libc/man...ex-select-1281


    [1] j'ai peur que les mutex boost puissent être dangereux dans le cas d'un appel à TerminateThread

    P.S. :
    - tu peux regarder le portage des Pthread pour windows pour voir ce qu'il est possible de faire
    - voici un fil intéressant à propos de TerminateThread : http://forums.microsoft.com/MSDN/Sho...61230&SiteID=1
    - je suppose qu'à l'aide d'évenement il est possible de faire pareil mais à la sauce microsoft (ce qui est plus propre quand on developpe pour cette plateforme)

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut
    Impeccable, le select a réglé mon soucis.
    Pas la solution idéale, mais ca marche, c'est mieux que rien!

    Merci

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

Discussions similaires

  1. Bloquer la lecture sur table un élément d'une table
    Par Blount dans le forum Requêtes
    Réponses: 0
    Dernier message: 01/09/2008, 10h07
  2. lecture sur une socket
    Par fattouch_squall dans le forum Développement
    Réponses: 7
    Dernier message: 22/12/2007, 13h57
  3. droit en lecture sur une feuille avec visual studio
    Par kingson dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 13/04/2007, 05h18
  4. Arrêter le lecture sur "cin".
    Par Pragmateek dans le forum SL & STL
    Réponses: 4
    Dernier message: 28/08/2006, 12h38
  5. Réponses: 2
    Dernier message: 16/05/2006, 14h17

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