2009-09-24 12 views
7

[związane this question]Qt sygnały i gniazda, wątki, app.exec() i związane z nimi pytania

Napisałem ten kawałek kodu, aby zrozumieć, w jaki sposób qt sygnały i gniazda pracować. Potrzebuję kogoś, kto wyjaśni to zachowanie i powie mi, czy mam rację co do własnych wniosków.

Mój program:

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(); 
} 

Teraz, r unning ten program wysyła go do nieskończonej pętli szukającej nowych połączeń.

Observation: jeśli nie zadzwonię pod numer app.exec(), program natychmiast powróci (tak jak powinien).
Question: dlaczego?

Question: czy połączyłem gniazdo jako połączenie oczekujące w kolejce, kiedy przeprowadzane jest wywoływanie automatów?
Question: jeśli app.exec() jest nieskończoną pętlą sortów, w jaki sposób sygnał newConnection() zostanie wyemitowany?

Big Question: Czy ma tu miejsce jakikolwiek "drugi wątek"? (I nie oczekiwać i nadzwyczaj eleganckie wyjaśnienie :))

Dzięki,
jrh

PS: Kto jeszcze ma ten zespół zagnieżdżone nawias? jak "(.. :))" lub "(.. (..))"?

Odpowiedz

11

Jeśli nie wywołasz app.exec(), to program trafi na koniec twojej głównej() i kończy. (Dlaczego? Nie ma więcej kodu do wykonania!)

app.exec() jest nieskończona pętla następującym stylu:

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

W przypadku korzystania z połączenia w kolejce, to zdarzenie zostanie dodany do listy kolejka zdarzeń i zostanie wykonana w pewnym momencie w przyszłości podczas pętli app.exec().

W twoim programie nie ma drugiego wątku. Zdarzenia są dostarczane asynchronicznie przez system operacyjny, dlatego wydaje się, że dzieje się coś jeszcze. Jest, ale nie w twoim programie.

+0

nadal pozostaje jedna rzecz: jeśli główna pętla zdarzeń jest zajęta uzyskiwaniem zdarzeń z systemu, kto je generuje? w jaki sposób emitowany jest sygnał 'newConnection()', jeśli główna pętla jest zajęta oczekiwaniem w tej pętli? – jrharshath

+0

@ harshath.jr - Nie używałem QTcpServer wcześniej, ale z dokumentacji wygląda na to, że prosi OS o dostarczenie zdarzeń Tcp do twojego programu. Kiedy twój program przetwarza zdarzenie tcp, QTcpServer robi to, czego potrzebuje, a następnie emituje newConnection(). – Bill

0

app.exec() wchodzi do głównej pętli zdarzeń i czeka, aż zostanie wywołana exit().

zmiana:
Główna pętla zdarzeń i kod generowany przez klej QMake zadbać o przeniesienie komunikat o zdarzeniu z QTcpServer do ConnectionHandler.

Jeśli używasz oczekujących połączeń, faktyczne połączenie z gniazdem QTcpServers będzie opóźnione, dopóki główna pętla zdarzeń nie wyświetli żądania połączenia .

0

Kiedy mówisz, że wchodzi w nieskończoną pętlę, masz na myśli awarię programu?

Ponieważ listen() stanie się częścią głównej pętli zdarzeń aplikacji w sposób, w jaki ją skonfigurowałeś, która będzie działać do momentu wyjścia z programu. Nie jestem pewien, na czym polega problem. Nie powinno być problemów z sygnałem emitowanym w głównej pętli zdarzeń aplikacji (exec()), gdy tylko się napotka.

Jeśli chcesz, możesz rozszerzyć klasę QThread na klasę ConnectionHandler i uruchomić listen() we własnym wątku, z wyjątkiem głównej pętli aplikacji.