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 :

[Thread] QThread et QSocket


Sujet :

Multithreading

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 81
    Points : 65
    Points
    65
    Par défaut [Thread] QThread et QSocket
    Bonjour,

    Je travaille actuellement sur une application multithread qui utilise un QSocket pour communiquer. Je rencontre certains plantages assez aléatoires que je n'arrive pas expliquer. En relisant la doc de Qt3, je suis tombé sur la partie Threads et QObject :

    Threads and QObject subclasses

    The QObject class itself is reentrant. However, certain rules apply when creating and using QObjects in a thread that is not the GUI thread.
    1. None of the QObject based classes included in the Qt library are reentrant. This includes all widgets (e.g. QWidget and subclasses), OS kernel classes (e.g. QProcess, QAccel, QTimer), and all networking classes (e.g. QSocket, QDns).
    2. QObject and all of its subclasses are not thread-safe. This includes the entire event delivery system. It is important to remember that the GUI thread may be delivering events to your QObject subclass while you are accessing the object from another thread. If you are using QObject in a thread that is not the GUI thread, and you are handling events sent to this object, you must protect all access to your data with a mutex; otherwise you may experience crashes or other undesired behavior.
    3. As a corollary to the above, deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly from a thread that is not the GUI thread. Use the QObject::deleteLater() method instead, which will cause the event loop to delete the object after all pending events have been delivered to the object.
    Je fais des appels aux fonctions d'écriture sur le socket à l'intérieur de la fonction run() de mon thread. Le programme plante justement à cet endroit et çà a l'air lié au problème de réentrance décrit dans le point 1 !

    Savez-vous si l'utilisation du mutex de QApplication pourrait m'aider à résoudre ce problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Test::run()
    {
      ...
      qApp->lock();             // est-ce que l'accès au socket est thread-safe ? 
      socket->writeBlock(data, len); 
      qApp->unlock();
      ...
    }
    Je utilise cette méthode assez couramment pour certains affichages rapides dans l'interface graphique mais je ne suis pas persuadé qu'il s'applique aussi facilement pour la classe QSocket étant donné que le transfert sur le réseau est asynchrone :
    Autrement dit, lorsque je sors de la fonction writeBlock, et que je libère le mutex, il se peut que le socket soit toujours utilisé au sein de mon thread, non ?

    Autre question : savez-vous si les mêmes contraintes de reentrance s'appliquent dans Qt4 ?

    Merci.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Points : 93
    Points
    93
    Par défaut
    Mais pourquoi utiliser QSocket depuis un QThread et pas depuis le thread principal ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Mais pourquoi utiliser QSocket depuis un QThread et pas depuis le thread principal ?
    Salut

    Simplement parce que l'application est fortement multithread et qu'à mon sens c'est l'API qui doit suporté le multithreading et ce n'est pas à l'utilisateur de se plier à des contraintes si fortes. Je pense que l'un des gros points faibles de Qt3 concerne ce point et sa faible robustesse vis à vis du multithreading.

    Je comprends parfaitement ce choix pour l'affichage graphique mais beaucoup moins pour des composants de type réseau.

    J'ai l'impression que Qt4 est plus efficace dans ce domaine et c'est pour cela que je finissais sur cette question :

    Autre question : savez-vous si les mêmes contraintes de reentrance s'appliquent dans Qt4 ?
    PS : je trouve que Qt est une lib très pratique et ce que je souhaiterais c'est pourvoir créer une classe qui hérite de QThread et de QWidget et de pouvoir émettre un signal dans mon run() sans faire planter l'appli !

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Points : 93
    Points
    93
    Par défaut
    QScoket a été écrit pour fonctionner en mode asynchrone, avec pour support de ce fonctionnement asynchrone la boucle d'évenements de Qt. Il faut donc utiliser QScoket dans le thread qui contient la boucle d'événements. Le fait que l'application soit "fortement multithread" ne change rien. Pourquoi tenter d'utiliser QSocket autrement ?

    Sinon, pour une utilisation avec des threads, il faut utiliser QSocketDevice. C'est une classe plus bas niveau, au fonctionnement synchrone. Elle ne dépend pas de la boucle d'événements.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Je comprends bien les contraintes imposées par la classe QSocket. Je trouve juste dommage que la boucle évènementielle de Qt3 ne soit pas mieux adaptée au multithreading.

    Je pense que le problème est réel, preuve en est que Qt4 offre une solution :

    Threads and QObjects

    QThread inherits QObject. It emits signals to indicate that the thread started or finished executing, and provides a few slots as well.

    More interesting is that QObjects can be used in multiple threads, emit signals that invoke slots in other threads, and post events to objects that "live" in other threads. This is possible because each thread is allowed to have its own event loop.
    Bref, je préfère passer à Qt4 plutôt que de réimplémenter une classe basée sur QSocketDevice (en espérant que la tache de travail soit moins grande).

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Il est clair que c'est mieux pour ton application.
    Le fait que chaque thread ait sa boucle évènementielle permet d'écrire un code plus simple à maintenir, en plus du fait que ça permette de gérer les échanges inter-threads plus facilement.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par G3G3 Voir le message
    Je pense que le problème est réel, preuve en est que Qt4 offre une solution :
    Le problème est réel, c'est vrai. Mais ça ne change rien à la question : Pourquoi tenter d'utiliser QSocket depuis un autre thread? Est-ce le goulot d'étranglement de l'application se trouve bien là ? Ce n'est généralement pas le cas.

    Attention aussi à ne pas en déduire que n'importe quel QObject peut être librement utilisé dans n'importe quel thread. Voir :Sinon, il est effectivement conseillé d'utiliser Qt 4 plutôt que Qt 3 pour écrire un nouveau programme. Qt 3 n'est plus maintenu.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Points : 93
    Points
    93
    Par défaut
    Ah, j'ai relu le post initial et je viens de comprendre :
    Citation Envoyé par G3G3 Voir le message
    Je travaille actuellement sur une application multithread qui utilise un QSocket pour communiquer.
    Ce n'est donc pas une question de performance. Si je comprends bien le besoin est de communiquer avec d'autre applications depuis n'importe quel thread de l'application. Dans l'absolu, nul besoin d'utiliser QSocket depuis d'autres threads que le thread GUI. Il faut communiquer depuis les thread non-GUI avec le thread GUI, par exemple via des événements, puis depuis le thread GUI avec d'autres applications via QSocket. Mais je suis d'accord que c'est bien compliqué par rapport à une utilisation directe de QSocket depuis les threads !

    QTcpSocket est réentrant dans Qt 4, ça devrait résoudre le problème.

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

Discussions similaires

  1. [QThread] créer un thread
    Par astrofan dans le forum Multithreading
    Réponses: 6
    Dernier message: 04/04/2009, 21h38
  2. [QThread] Probleme lorsque le thread s'execute deux fois
    Par poulecaca dans le forum Multithreading
    Réponses: 15
    Dernier message: 30/12/2008, 18h01
  3. [Thread] Synchronisation d'un QThread avec l'IHM
    Par cfdev dans le forum Multithreading
    Réponses: 12
    Dernier message: 04/06/2008, 00h21
  4. [Thread] Comment faire fonctionner QThread?
    Par Elv13 dans le forum Multithreading
    Réponses: 1
    Dernier message: 07/05/2008, 15h49
  5. [Thread] class QThread
    Par tody1234 dans le forum Multithreading
    Réponses: 5
    Dernier message: 28/04/2008, 09h13

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