QThread: Subclasses erstellen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
saoirse
Beiträge: 18
Registriert: 16. April 2011 17:49

QThread: Subclasses erstellen

Beitrag von saoirse »

Hi,

ich möchte gern mehrere UDP-Protokoll-Classes erstellen, die alle von der QThread-Class abgeleitet sind.

Code: Alles auswählen

class UdpThread: public QThread
{

public:
    virtual void run();
    virtual void ProzessPkt(QString &data) = 0; //implementiert in subclasses

private:
    void receivePkt(); 
};


//UdpThread.cpp:

void UdpThread::receivePkt()
{
    //get rcvd pkt

    QString pktString; 
    ProzessPkt( pktString); 
}


//in der QMainWindow.cpp wird / soll thread gestartet werden 

void MainWindow::StartUdpThreads()
{
   //member-variablen
    m_pDhcpThread = new DhcpThread (); 
    m_pDhcpThread->Start(); 

    m_pSnmpThread = new SnmpThread (); 
    m_pSnmpThread->Start();     
}



class DhcpThread : public UdpThread
{

public:
    virtual void ProzessPkt(QString &data); 
};

class SnmpThread : public UdpThread
{

public:
    virtual void ProzessPkt(QString &data)
}; 
Muss ich die run() Methode auch in die SnmpThread und DhcpThread Classes implementieren als virtual void run(), welche dann zu Beginn aufgerufen werden und am Schluss die run() Methode der UdpThread-Class aufruft?

Im Prinzip möchte ich erreichen, dass man innerhalb der UdpThread-Class beim Empfangen eines Packets (Ethernet) sofort weiß welche Subclass bei ProzessPkt() aufgerufen werden muss.

Gruß
saoirse
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: QThread: Subclasses erstellen

Beitrag von franzf »

saoirse hat geschrieben:Im Prinzip möchte ich erreichen, dass man innerhalb der UdpThread-Class beim Empfangen eines Packets (Ethernet) sofort weiß welche Subclass bei ProzessPkt() aufgerufen werden muss.
Das willst du NICHT! Für solch Sachen gibt es virtual. Wenn du an einer Stelle darauf angewiesen bist, zu wissen was für ein spezielle Klasse gerade vorliegt, hast du recht wahrscheinlich einen Designfehler gebastelt.

Ansonsten:
Die ganzen Netzwerk-Sachen laufen asynchron, Threads werden hier nicht mehr benötigt.
QUdpSocket kennst du schon?
UDP (Transportschicht) und DHCP (Anwendung) haben bis auf diese Verknüpfung NICHTS miteinander zu tun. Ableiten ist Käse^3. Schau dir mal bei Wikipedia die Artikel an, damit du ungefähr nen Eindruk davon bekommst.
saoirse
Beiträge: 18
Registriert: 16. April 2011 17:49

Beitrag von saoirse »

Die ganzen Netzwerk-Sachen laufen asynchron, Threads werden hier nicht mehr benötigt
Ich wollte die Netzwerk-Sachen / Threads in einen eigenen Thread packen, damit die GUI dadurch nicht belastet wird. QUdpSocket kenne ich und verwende ich ja auch in meiner UdpThread class, um dort die Pakete zu empfangen.
UDP (Transportschicht) und DHCP (Anwendung) haben bis auf diese Verknüpfung NICHTS miteinander zu tun
Das weiß ich: ich wollte ja auch eine UdpThread-Socket class erstellen, und darüber aufbauend die einzlenen Application-Ebenen wie DHCP: dann erstelle ich eine Membervariable von DhcpThread und SnmpThread, deren Subclass die UdpThread class ist.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

saoirse hat geschrieben:Ich wollte die Netzwerk-Sachen / Threads in einen eigenen Thread packen, damit die GUI dadurch nicht belastet wird. QUdpSocket kenne ich und verwende ich ja auch in meiner UdpThread class, um dort die Pakete zu empfangen.
Asynchron bedeutet nicht blockierend. Wenn du einen asynchrone Funktion aufrufst, wird nur die Arbeit angestoßen, die Funktion kehrt sofort zur aufrufenden Stelle zurück, während im Hintergrund gearbeitet wird (Abschicken des Requests, Warten auf die Antwort, Auswerten der Antwort, usw.) Wenn du eh QUdpSocket verwendest, hast du schon gewonnen. Einfach eigene SLOTS an die passenden SIGNALS hängen und fertig.
dann erstelle ich eine Membervariable von DhcpThread und SnmpThread, deren Subclass die UdpThread class ist.
Dann muss aber DhcpThread nicht von UdpThread erben.
Erben = Ist-Ein-Beziehung. Du machst hier Komposition: Hat-Ein- oder Verwendet-Ein-Beziehung.
saoirse
Beiträge: 18
Registriert: 16. April 2011 17:49

Beitrag von saoirse »

Dann muss aber DhcpThread nicht von UdpThread erben.
Erben = Ist-Ein-Beziehung. Du machst hier Komposition: Hat-Ein- oder Verwendet-Ein-Beziehung.
ok, das bedeutet ich installier zwei Klassen (DhcpThread und SnmpThread) die beide von QThread abgeleitet sind und installiere darin meine beiden QUdpSocket-Objecte.

Les mich grad noch in die Thematik QThreads ein bei QT: bin über die movetothread() Methode gerade gestolpert. Die benötige ich aber in meinem Fall ja gar nicht mehr.

Code: Alles auswählen

void DhcpThread::run()
{
    m_pUdpSock = new QUdpSocket();
    m_pUdpSock ->bind(PORT);

    m_pUdpSock->exec(); 
}  
Und zu Beginn befor ich DhcpThread::start() im Mainthread aktiviere, übergebe ich dem DhcpThread noch alle wichtigen Variablen / Membervariablen des Mainthreads, damit der DhcpThread mittels Slots und Signale z.B. die recv Daten an den Mainthread übergeben kann.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Dein jetziger Ansatz bringt NULL Verbesserung gegenüber der Variante ohne Thread: Im run() hast du kein exec() (schau dir die QThread-Doku an, damit du weißt von welchem exec() ich spreche), damit werden die angehangenen SLOTS im MainThread abgearbeitet, was im schlimmsten Fall die Gui zum Hängen bringt.

Aber warum du permanent meinen Hinweis ignorierst, dass die Qt-Sockets (wie Netzwerk-Apis überhaupt) schon asynchron arbeiten, und dein Thread-Gefummel (mit dem du scheinbar noch wirklich Probleme hast) absolut unnötig ist, versteh ich nicht. Einfach wie das Beispiel aus der Doku zu QUdpSocket machen, dann hast du keine Probleme.
Die Daten kommen eh häppchenweise, wenn das Auswerten sooo lange dauert (was du erst merkst, wenn dein Programm mal läuft, alles andere ist unnötige "premature optimization"), kannst du die auch später in einem eigenen Thread auswerten. Das Empfangen ist aber richtig schnell und erfordert keinen eigenen Thread.
Antworten