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

Multithreading Discussion :

Conflit XLib : Unknown request in queue while dequeuing [QThread]


Sujet :

Multithreading

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut Conflit XLib : Unknown request in queue while dequeuing
    Bonjour,

    Je suis sur Ubuntu 11 et utilise QT4.7.3 avec QTCreator 2.2.1.
    Dans une application multi-thread utilisant une classe héritant de QThread, et affichant des fenêtres OpenCV, j'obtiens parfois cette erreur qui interrompt mon programme :

    [xcb] Unknown request in queue while dequeuing
    [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
    [xcb] Aborting, sorry about that.
    Après quelques recherches, il semblerait que lorsque des threads sont susceptibles d'utiliser des éléments de XLib, il faille appeler avant toute création de thread, XInitthread();

    J'ai donc ajouté ceci à mon programme dans le main :

    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
     
    ...
    #include <X11/Xlib.h>
    ...
     
     
    /** @function main */
    int main( int argc, const char** argv )
    {
     
        XInitThreads();
     
        // Do something
     
        return  0;
    }
    Or, ce nouvel include me provoque une bonne cinquantaine d'erreurs de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /usr/include/qt4/QtCore/qtextstream.h:60: error: #error qtextstream.h must be included before any header file that defines Status
    /usr/include/opencv2/flann/dist.h:82: error: expected unqualified-id before numeric constant
    Après d'autres recherces, il semblerait que le souci apparaisse à cause des classes True et False dans dist.h, qui seraient en conflit avec d'autres classes du même nom quelque part.

    Dans dist.h il y a :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class True
    {
    };
     
    class False
    {
    };
    Et à partir de là je ne sais plus comment faire pour régler ce problème, qui semble être récurrent sous Ubuntu 11.

    Avez-vous quelques idées ?

    Merci d'avance et bonne journée

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035

  3. #3
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut
    Très bien je vais passer par de signaux et de slots. Je pensais que l'utilisation de mutex suffirait.
    Je vais essayer ça et reviens mettre le post en "résolu" si c'est le cas.
    Qt garantit que l'exécution de slots est thread-safe n'est-ce pas ?

    Merci et bonne journée.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Si son appel dépend d'un connect oui. (faut laisser le mode de conection par défaut)

    Sinon, c'est une fonction comme une autre avec les même problème de multithread


    Citation Envoyé par Shargat Voir le message
    Très bien je vais passer par de signaux et de slots. Je pensais que l'utilisation de mutex suffirait.
    Je vais essayer ça et reviens mettre le post en "résolu" si c'est le cas.
    Qt garantit que l'exécution de slots est thread-safe n'est-ce pas ?

    Merci et bonne journée.

  5. #5
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2008
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2008
    Messages : 138
    Par défaut
    Merci.

    Après avoir implémenté les signaux et slots pour qu'un seul thread gère l'affichage d'éléments graphiques de XLib, j'obtiens un comportement aléatoire.

    Parfois, le programme tourne, parfois l'erreur suivante apparait après qu'un thread soit lancé:

    Fatal IO error 11 (Resource temporarily unavailable) on X server :0.
    et parfois je revois cette erreur :

    [xcb] Unknown sequence number while processing queue
    [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
    [xcb] Aborting, sorry about that.
    test3_FaceThread_algo: ../../src/xcb_io.c:273: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
    Je suis un peu paumé. Je vais regarder un peu d'où peuvent venir ces erreurs.
    Ca semble rappeler l'erreur initiale de ce post, car liée au système graphique X11. Mon programme utilise OpenCV et affiche différentes frames. L'affichage des frames est actuellement assurée par un seul objet singleton encapsulé dans un QThread réveillé par les signaux que lui envoient les différents autres threads pour qu'il affiche une donnée.

    Merci pour ton aide en tout cas.

    EDIT :

    Bon il semblerait que je fasse tout de travers. Désolé mais je ne suis pas familier de la programmation multi-thread.
    Ci-dessous, je crée un thread et son objet encapsulé :

    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
     
    class Displayer : public QObject
    {
        Q_OBJECT
     
    public slots:
        void displayMat(Mat*, QString);              // Slot displaying the Mat image
     
    };
     
     
     
    class DisplayerThread : public QThread
    {
        Q_OBJECT
     
    protected:
        void run()
        {
            // Create internal object
            Displayer _displayer;
            // Connect input slots to output slots
            connect(this,SIGNAL( displayMat(Mat*, QString)),&_displayer,SLOT( displayMat(Mat*, QString)));
            // Run eventLoop
            exec();
        }
     
    signals:
        void displayMat(Mat*, QString);
    };
    Et ci-dessous le singleton qui encaspule ce thread (le thread doit être un singleton accessible dans le programme) :

    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
     
    class SingletonDisplayThread
    {
    private :
        SingletonDisplayThread();
     
    public :
        static DisplayerThread* getInstance() {
            if (_displayThread == NULL)
            {
                _displayThread =  new DisplayerThread();
                _displayThread->start();
            }
     
            return _displayThread;
        }
     
        static void kill ()
        {
            if (_displayThread != NULL)
            {
                _displayThread->exit();
               _displayThread->wait();
     
                delete _displayThread;
                _displayThread = NULL;
            }
        }
     
    private :
        static DisplayerThread* _displayThread;
    };
    DisplayerThread* SingletonDisplayThread::_displayThread = NULL;
    Et enfin, voici dans mon thread principal comment je lance tout ce petit monde :

    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
     
                for (int i = 0; i < faces.size(); i++)
                {
                            /// We create and run a new FaceThread
                            QThread* thread = new QThread;
                            FaceTracker* tracker = new FaceTracker(currentFace, frame, &_captureV);
                            tracker->moveToThread(thread);
                            QObject::connect(thread, SIGNAL(started()), tracker, SLOT(process()));
                            QObject::connect(tracker, SIGNAL(finished()), thread, SLOT(terminate()));
                            QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
                            QObject::connect(tracker, SIGNAL(askDisplayMat(Mat*,QString)), SingletonDisplayThread::getInstance(), SIGNAL(displayMat(Mat*,QString)));
                            thread->start();
                            tabThreads.push_back(thread);
          }
     
     
     /// We wait until all the tracker finish
                for(int j = 0;j < tabThreads.size(); j++)
                {
                     (QThread*)(tabThreads.at(j))->wait();
                }
    Outre les erreurs évoquées ci-dessus, lorsque le programme se lance correctement, les threads créés plus haut ( pas le singleton, les autres ) semblent ne jamais s'arrêter. Le programme reste bloqué dans la dernière boucle for, en attente de terminaison des threads. Pourtant je fais bien

    à la fin de l'exécution de ces threads.

    Qu'est-ce que je fais mal ? Je soupçonne le thread de ne pas recevoir le signal "finished" du tracker.

    Merci d'avance, j'ai passé 2 heures à tenter de déboguer ce code, sans succès.

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Il semble que tu est un problème entre les QObject et leurs association avec les threads. Mais je n'en suis pas sure. Tu semble avoir compris le principe.

    Qui t'affiche l'image?

    Pour qu'un slot s’exécute dans un thread, il faut que l'eventloop du thread soit lancée et qu'elle soit pas bloquée par une exécution quelconque.

    Peux tu expliquer un peu ce que font tes threads?

    En regardant ton code, je me demande si tu ne devrais pas plutôt utiliser les QtConcurrent :
    http://qt-project.org/doc/qt-4.8/qtconcurrentmap.html

    Et avec un QFutureWatcher, tu pourra même éviter d'attendre la fin du calcul.
    http://qt-project.org/doc/qt-4.8/qfuturewatcher.html

    Le gros avantage c'est qu'il va utiliser un nombre de thread cohérent avec ta machine et que tu peux utiliser les thread de manière implicite.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 07/10/2010, 17h56
  2. Erreur "Caught exception while handling request"
    Par URIOS dans le forum Web & réseau
    Réponses: 13
    Dernier message: 31/03/2009, 21h28
  3. [MySQL] conflit entre deux fonction while
    Par guillaumeIOB dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 04/12/2006, 12h56
  4. [MySQL] Conflit entre deux fonction WHILE
    Par guillaumeIOB dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 28/11/2006, 18h15
  5. [XSLT] Error while parsing XSL file (unknown protocol: e)
    Par SONY30 dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 26/09/2006, 13h58

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