Frage zu Threadfunktion in Klasse



  • Hi,

    ich würde gerne in meiner Klasse einen Thread starten. Allerdings sehe ich da einige Probleme:

    Wer schließt das Handle?
    Was passiert mit den Membervariablen nach verlassen des Scopes? Kann ich noch darauf zugreifen? Eigentlich sollte das Objekt doch zerstört werden. Die Funktion ist zwar statisch, aber zumindest die Membervariablen würden bei drauf gehen, oder?

    Folgendes habe ich ausprobiert:

    #include <iostream>
    #include <windows.h>
    
    class Server
    {
    private:
    	HANDLE hThread;
    	DWORD dwThreadId;
    
    public:
    	Server()
    	{
    		std::cout << "Starting thread" << std::endl;
    		hThread = CreateThread(NULL, 0, serverFunc, 0, 0, &dwThreadId);
    	}
    
    	~Server()
    	{
    		std::cout << "Cleaning up" << std::endl;
    		CloseHandle(hThread);
    	}
    
    protected:
    	static DWORD WINAPI serverFunc(LPVOID data)
    	{
    		while (true)
    		{
    			std::cout << "Server" << std::endl;
    		}
    
    		return 0;
    	}
    };
    
    int main()
    {
    	{
    		Server serv;
    	}
    	while (true)
    	{
    		;
    	}
    }
    

    Das funktioniert zwar, aber sieht für mich seeeeeeehr schlecht aus. Wie löst man sowas? Sollte ich eine Funktion "start()" und eine funktion "end()" erstellen und die Klasse in der Main erstellen? Vielleicht so:

    int main()
    {
      Server serv;
      serv.start(); // CreateThread...
      serv.wait(); // WaitForSingleObject...
      serv.end(); // CloseHandle...
    }
    

    Was denkt ihr?

    Danke 🙂


  • Mod

    So ist es!
    Auf dem Stack geht es nicht. Wennn der Thread auf Variablen in der Klasse zugreift, dann knallt es.

    Ich würde die Klasse so bauen wie die CWinThread Klasse der MFC. Diese kann mit einem AutoDelete versehen werden. Sprich zerstört sich bei Ende des Threads.

    Wird autodelete auf false gesetzt wird, nichts entsorgt und der Erzeuger der Instanz ist für das entsorgen verantwortlich.

    CloseHandle natürlich im Destruktor...



  • Martin Richter schrieb:

    So ist es!
    Auf dem Stack geht es nicht. Wennn der Thread auf Variablen in der Klasse zugreift, dann knallt es.

    Ich würde die Klasse so bauen wie die CWinThread Klasse der MFC. Diese kann mit einem AutoDelete versehen werden. Sprich zerstört sich bei Ende des Threads.

    Wird autodelete auf false gesetzt wird, nichts entsorgt und der Erzeuger der Instanz ist für das entsorgen verantwortlich.

    CloseHandle natürlich im Destruktor...

    Am liebsten würde ich das ohne MFC lösen 🙂 Wie sollte ich da am Besten vorgehen?


  • Mod

    Dann machst Du es eben ohne...

    Bau eine Baisklasse, die einen Thread startet und eine virtuelle Funktion Do aufruft, dazu noch nette passende Funktionen Init/Uninit. Nette Accesoren wie IsRunning, Stop etc. Sind auch nicht schlecht, dazu für ein Events Stopped, Running, Initialized, Uninitializied, damit man extern gut mal auf den Thread warten kann.
    Dazu packst Dunoch ein AutoDelete Flag rein, das dafür sorgt dass das Handle geschlossen wird und ein delete this ausgeführt wird. Das ist nicht mehr als ein 30 Zeiler...



  • Martin Richter schrieb:

    Dann machst Du es eben ohne...

    Bau eine Baisklasse, die einen Thread startet und eine virtuelle Funktion Do aufruft, dazu noch nette passende Funktionen Init/Uninit. Nette Accesoren wie IsRunning, Stop etc. Sind auch nicht schlecht, dazu für ein Events Stopped, Running, Initialized, Uninitializied, damit man extern gut mal auf den Thread warten kann.
    Dazu packst Dunoch ein AutoDelete Flag rein, das dafür sorgt dass das Handle geschlossen wird und ein delete this ausgeführt wird. Das ist nicht mehr als ein 30 Zeiler...

    Mir ist das alles klar bis auf das AutoDelete Flag. Wird im Dekonstruktor einfach der Thread beendet, falls AutoDelete auf true steht? Oder wie wird das geregelt? 🙂 Und was passiert falls AutoDelete auf false steht? Im Prinzp müsste man das Handle dann ja nie wieder schließen können. Macht das AutoDelete Flag also überhaupt Sinn?

    Du hast mir jedenfalls schon wirklich sehr weitergeholfen. Danke dafür 🙂


  • Mod

    Autodelete beudetet:
    Wenn der Thread terminiert wird einfach delete this aufgerufen und das Thread-Objekt zersört sich von selbst.


Anmelden zum Antworten