Comment exécuter les fonctions qtcpsocket dans un fil différent? p>
4 Réponses :
mettre un qmutex code> verrouille autour de tous les appels, pas seulement sur le thread "différent", mais sur tous les filets. Un moyen facile de le faire est via un
qmutexocker code> p>
" Remarque: B> Toutes les fonctions de cette classe sont réentrantes" . Si vous avez une source plus autoritaire pour votre revendication contradictoire, veuillez inclure cela.
Tu as raison. Cependant, (et ce que je voulais dire était) la classe n'est pas thread-coffre-fort, et la ré-entrante ne garantit que vous pouvez utiliser la classe à partir de plusieurs threads si vous avez des instances différentes, mais différent qtcpsocket code> Les instances ne peuvent pas partager des descripteurs de socket. De plus, une seule instance d'un
qtcpsocket code> n'est pas accessible à partir de threads multiples, que ce soit muté de la mutilation.
Les documents QT sont explicites que le Je suppose que vous implémentez quelque chose comme un serveur Web où l'écoute crée un La façon dont j'ai travaillé autour de cela est que j'ai gardé la prise dans le fil, elle est née. J'ai réparé toutes les données entrantes dans ce fil et jeté dans une file d'attente où un autre fil pouvait fonctionner sur ces données. P >
Remarque: Si une autre prise est créée dans la réimplémentation de cette méthode, elle doit être ajoutée au mécanisme de connexions en attente en appelant Remarque: Si vous souhaitez gérer une connexion entrante sous la forme d'un nouvel objet qtcpsocket code> ne doit pas être utilisé de fils d'accrocs. I.E, créez un
qtcpsocket code> dans le fil principal et faites attacher le signal à un objet dans un autre thread. P>
qtcpsocket code> sur l'acceptation. Vous voulez alors un autre fil de traitement de la tâche de traitement de cette prise. Vous ne pouvez pas. P>
Vide virtuel Incomingconnection (QItPtr SocketDescriptor) code> < / a> h3>
addPendingConnection () code>. p>.
qtcpsocket de code> dans un autre thread, vous devez
socketDescriptor code> à l'autre fil et créez L'objet
qtcpsocket code> là-bas strong> et utilisez son
setsocketDescriptor () code> méthode. p>
blockQuote>
Où dit-il ça?
Cette note a été ajoutée par la communauté et dans mon expérience empericale n'est pas correcte. Il ne semble pas non plus que vous puissiez simuler le comportement en passant des descripteurs de socket tels qu'ils prétendent, car vous vous retrouvez avec deux qtcpsocket code> (l'enfant implicite du serveur et l'instance que vous créez dans le nouveau fil) Sur le même descripteur, qui provoque des défaillances d'affirmation de temps d'exécution.
Vous dites que vous "entretenue toutes les données entrantes dans ce fil et jeté dans une file d'attente dans laquelle un autre fil pouvait fonctionner sur ces données." Comment est-ce que tu fais ça?
@Nicolasholthaus, a ajouté une note de sauvegarde de la réponse. Je suis également confronté à un crash où je déplace un qtcpsocket code> créé dans un fil principal sur un autre fil de travail. Lors de la vérification de la trace de pile, il apparaît que le thread principal conserve encore un objet de type
qsslsocketbackendprivate code> qui écrit les données. Cela provoque l'accident. Dans le passé, j'étais mal compris cette situation et je blâmais la question sur mon erreur de codage. Mais il semble qu'il y a quelque chose qui ne va pas avec la bibliothèque QT. Voir Ce . Quelle est la bonne façon de déplacer une prise TCP sur un autre fil?
@iammilind Il est préférable de ne pas les déplacer, mais de créer i> dans un fil différent. J'ai ajouté une réponse montrant l'idiome que j'utilise pour le faire.
Ce que j'ai lu dans le docs est celui Qtcpsocket ne doit pas être utilisé sur les threads. Si vous souhaitez l'utiliser dans un autre thread DOCS DOCS, vous devez créer une nouvelle instance QTcpsocket dans votre thread et définir le descripteur de la nouvelle instance. Pour ce faire, vous devez réimplément qtcpserver et utiliser Qtcpserver :: IncomingConnection . Un exemple simple est fourni ici . P>
Il est important de noter ce que vous pouvez et ne pouvez pas faire en termes de filetage vous peut strud> l'utiliser dans un fil non principal, mais seulement le fil dans lequel il a été créé. em> p> p> p> l> p> l>
vous ne peut pas strud> Appeler différentes fonctions sur le imo, mettez votre Io, y compris où Vous voudrez également connecter un signal (j'appelle habituellement cela I Utilisez également une variable de condition pour attendre après avoir créé le fil jusqu'à la démarrage de la boucle d'événement. Ce n'est pas nécessaire, mais si vous mettez ces threads ensemble dans des constructeurs, cela peut aider à rendre le flux de programme a plus de sens. P> p> qtcpsocket code>:
qtcpsocket code> à partir de différents threads, par ex. Lisez dans un fil, écrivez-vous dans l'autre. Au lieu de cela, vous pouvez créer un fil séparé pour chaque
qtcpsocket code>, ce qui les empêche d'utiliser du temps et des ressources pouvant peindre vos widgets dans le fil principal. P> LI>
ul>
qtcpsocket code> dans un fil autre que le thread principal est une meilleure pratique et doit-le faire pour toute application performante. J'utilise
qtcpsocket code> dans des threads non principaux tout le temps à l'aide de l'idiome suivant: p>
m_thread code> est membre Fil (essentiellement simplement en veillant à ce qu'il ait une durée de vie supérieure à la portée actuelle) et
m_concurrentqueue code> est une file d'attente de fil-sécurité ou
std code> conteneur avec la protection mutex. p>
joinall code>) à la fonction de démission de la boucle d'événement et l'appelez à partir du destructeur de classe. Lorsque vous utilisez un idiome d'événement-boucle-in-a-fil, vous devez toujours faire attention à vous assurer de pouvoir détruire la classe correctement, sinon votre programme ne quitte pas (ou sous Windows, il sera terminé, généralement avec certains destructeurs. Ne pas être appelé, et cela finit par être une erreur silencieuse). p>
Merci pour votre réponse. J'ai déjà évoqué le jour où vous avez posté. J'avais trouvé ce fait que ce fait que le qtcpsocket code> ou
qwebsocket code> ne sont pas thread-mobiles! Ont soulevé un bug à QT à cet égard et la mettre sous la question ci-dessus.
@Nicolas, cette solution a l'air géniale mais je blessais comment gérer les données de m_concurrentqueue code> dans le fil principal, je veux dire devrais-je utiliser
qticer code> ou simplement signaler pour notifier le fil principal pour démarrer la poignée Données en files d'attente? Quelle variante est la meilleure en termes de performance? Merci.
Y a-t-il une raison pour laquelle vous utilisez une lambda pour eventLoop.quit au lieu de & qeventloop :: Quitter code>?
@cdgraham Je ne pense pas que cela a probablement copié de quelque chose qui a fait un certain nettoyage à la sortie.
Ce n'est pas possible b>. J'ai appris cela difficile. Voir Ma question . Ont soulevé une suggestion de bugs à qt à
movetothread () = Supprimer code> pour ces sockets et classes de serveur. Qtbug-82373