2010-04-23 7 views

Répondre

-2

Voici l'exemple:

fichier

thread.h:

class Thread : public QThread { 
    Q_OBJECT 
public: 
    Thread(); 
protected: 
    void run(); 
} 
fichier

thread.cpp:

Thread::Thread() {} 
void Thread::run() { 
    // do what ever you want with QTcpSocket 
} 

dans le principal. cpp ou peu importe:

Thread *myThread = new Thread; 
connect(myThread, SIGNAL(finished()), this, SLOT(on_myThread_finished())); 
myThread->start(); 
+2

C'est faux sur tant de niveaux. Vous n'essayez même jamais de déplacer le QTcpSocket vers le nouveau thread, ce qui est fondamental pour n'importe quelle application QThread, et en plus, cela ne fonctionnerait pas car la classe QTcpSocket n'est pas thread-safe et a une affinité intégrée qui provoque le run- échecs d'assertion de temps si vous tentez de l'invoquer à partir de n'importe quelle classe autre que celle dans laquelle elle a été construite (quel que soit le thread dans lequel votre QTcpServer s'exécute) –

1

Mettez un verrou QMutex autour de tous les appels, pas seulement sur le thread "différent" mais sur tous les threads. Un moyen facile de le faire est par un QMutexLocker

+0

["** Remarque: ** Toutes les fonctions de cette classe sont réentrantes"] (http://qt-project.org/doc/qt-4.7/qtcpsocket.html). Si vous avez une source plus fiable pour votre réclamation contradictoire, veuillez l'inclure. – MSalters

+0

Vous avez raison. Cependant, (et ce que je voulais dire) la classe n'est pas thread-safe, et la ré-entrée garantit seulement que vous pouvez utiliser la classe de plusieurs threads si vous avez différentes instances, mais différentes instances de 'QTcpSocket' ne peuvent pas partager des descripteurs de socket . De plus, une seule instance d'un 'QTcpSocket' ne peut pas être accédée à partir de plusieurs threads, qu'elle soit ou non mutexée. –

6

Les docs QT sont explicites que le QTCPSocket ne doit pas être utilisé à travers les threads. I.E, créer un QTCPSocket dans le thread principal et avoir le signal lié à un objet dans un autre thread.

Je suppose que vous implémentez quelque chose comme un serveur Web où l'écoute crée un QTCPSocket sur l'acceptation. Vous voulez ensuite un autre thread pour gérer la tâche de traitement de ce socket. Tu ne peux pas. La façon dont j'ai travaillé autour de cela est que j'ai gardé le socket dans le fil dans lequel il est né. J'ai géré toutes les données entrantes dans ce fil et l'ai jeté dans une file où un autre thread pourrait travailler sur ces données.

+0

Où est-ce que cela dit? –

+0

Voir http://qt-project.org/doc/qt-4.7/qtcpserver.html#note-33 –

+0

Cette note a été ajoutée par la communauté, et dans mon expérience de l'empereur n'est pas correcte. Il ne semble pas non plus que vous puissiez simuler le comportement en passant des descripteurs de socket comme ils le prétendent, puisque vous vous retrouvez avec deux instances 'QTcpSocket' (l'enfant implicite du serveur et l'instance que vous créez dans le nouveau thread) s'exécutant sur le même descripteur, ce qui provoque des échecs d'assertion d'exécution. –

0

Ce que je lis dans les docs est que QTcpSocket ne doit pas être utilisé sur plusieurs threads. Si vous souhaitez l'utiliser dans un autre thread, les docs Qt disent que vous devez créer une nouvelle instance QTcpSocket dans votre thread et définir le descripteur sur la nouvelle instance. Pour ce faire, vous devez réimplémenter QTcpServer et utiliser QTcpServer::incomingConnection. Un exemple simple est fourni here.

Questions connexes