2009-09-24 5 views
7

[liés à this question]signaux Qt et fentes, fils, app.exec(), et les requêtes connexes

moi avons écrit ce morceau de code pour comprendre comment les signaux qt et fentes fonctionnent. J'ai besoin de quelqu'un pour expliquer le comportement et pour me dire si j'ai raison sur mes propres conclusions.

Mon programme:

connectionhandler.h

#ifndef CONNECTIONHANDLER_H 
#define CONNECTIONHANDLER_H 

#include <QTcpServer> 
class ConnectionHandler : public QObject 
{ 
    Q_OBJECT 
public: 
    ConnectionHandler(); 
public slots: 
    void newConn(); 
private: 
    QTcpServer *server; 
}; 

#endif // CONNECTIONHANDLER_H 

connectionhandler.cpp

#include "connectionhandler.h" 
#include <QTextStream> 

ConnectionHandler::ConnectionHandler() { 
    server = new QTcpServer; 
    server->listen(QHostAddress::LocalHost, 8080); 
    QObject::connect(server, SIGNAL(newConnection()),this, SLOT(newConn())); 
} 
void ConnectionHandler::newConn() { 
    QTextStream out(stdout); 
    out << "new kanneksan!\n"; 
    out.flush(); 
} 

main.cpp

#include <QCoreApplication> 
#include "connectionhandler.h" 

int main(int argc, char* argv[]) { 
    QCoreApplication app(argc,argv); 
    ConnectionHandler handler; 
    return app.exec(); 
} 

Maintenant, r Unning ce programme l'envoie dans une boucle infinie à la recherche de nouvelles connexions.

Observation: Si je n'appelle pas app.exec(), le programme revient immédiatement (comme il se doit).
Question: pourquoi?

Question: Si j'avais connecté l'emplacement en tant que connexion en file d'attente, à quel moment l'appel de l'emplacement serait-il effectué?
Question: Si app.exec() est une sorte de boucle infinie, comment le signal newConnection() est-il jamais émis?

Big Question: Est-ce que leur «deuxième thread» est impliqué ici? (Je me attends pas, et une explication étonnamment élégant :))

Merci,
HJR

PS: qui d'autre ce syndrome imbriqué entre parenthèses? comme "(.. :))" ou "(.. (..))"?

Répondre

11

Si vous n'appelez pas app.exec(), le programme atteint la fin de votre main() et se termine. (Pourquoi il n'y a pas plus de code à exécuter!)

app.exec() est une boucle infinie du style suivant:

do 
{ 
    get event from system 
    handle event 
} 
while (true); 

Si vous utilisez une connexion en file d'attente, l'événement est ajouté à votre la file d'attente d'événements, et elle sera effectuée à un moment donné dans le futur au cours de la boucle app.exec().

Il n'y a pas de deuxième thread dans votre programme. Les événements sont livrés de manière asynchrone par le système d'exploitation, ce qui explique pourquoi il se passe quelque chose d'autre. Il y a, mais pas dans votre programme.

+0

il reste encore une chose: si la boucle d'événement principal est occupée à recevoir des événements du système, qui les génère? comment le signal 'newConnection()' est-il jamais émis, si la boucle principale est occupée dans cette boucle? – jrharshath

+0

@ harshath.jr - Je n'ai jamais utilisé QTcpServer auparavant, mais à partir de la documentation, il semble qu'il demande au système d'exploitation de fournir des événements Tcp à votre programme. Lorsque votre programme traite cet événement tcp, QTcpServer fait ce qu'il doit faire, puis émet newConnection(). – Bill

0

app.exec() entre dans la boucle d'événement principal et attend jusqu'à ce que exit() soit appelée.

mise à jour:
La boucle principale de l'événement et le code de colle généré par qmake prendre soin de transférer le message d'événement du QTcpServer à votre ConnectionHandler.

Si vous utilisiez des connexions en file d'attente, la connexion réelle à l'emplacement QTcpServers serait retardée jusqu'à ce que la boucle d'événements principale transmette la demande de connexion .

0

Lorsque vous dites qu'il entre dans une boucle infinie, vous voulez dire qu'il plante le programme? Parce que listen() fera partie de la boucle d'événement d'application principale de la façon dont vous l'avez configuré, qui s'exécute jusqu'à ce que vous quittiez le programme. Je ne suis pas sûr du problème. Il ne devrait pas y avoir de problème d'émission de votre signal dans la boucle d'événement de l'application principale (exec()) à chaque fois que vous en rencontrez un. Si vous le souhaitez, vous pouvez faire en sorte que votre classe ConnectionHandler étende QThread et lance listen() dans son propre thread, en dehors de la boucle principale de l'application.

Questions connexes