[gelöst] Multithreading Class Problem



  • Hallo zusammen,

    ich habe eine Klasse in der eine Funktion als Thread gestartet wird. Dieser Thread greift auf private Variablen zu.
    Dieses funktioniert bei einem Objekt fehlerfrei. Läuft der Thread aktiv und ich versuche mit einem weiterem Objekt der Klasse diesen Thread zu starten, haben beide Threads keinen eigenen Variablenraum sondern "verlieren" diesen.

    Ich programmiere mit VS2010 Prof

    Das ist nicht meine richtige Klasse, der Grundcode ist jedoch identisch:

    Klasse:

    class Test
    {
    private:
    	struct Daten
    	{
    		string	Test1;
    		int		zahl;
    		HANDLE	hthread;
    		DWORD	id;
    	} _d;
    
    public:
    	Test()
    	{}
    	~Test()
    	{}
    
    	void start_thread ();
    
    private:
    	static DWORD WINAPI	_Thread			(LPVOID Pointer);
    	void				_Thread_start	();
    
    };
    

    Mit der Funktion start_thread() wird der Thread angestoßen:

    void start_thread()
    {
    	_d.hthread = CreateThread(NULL, 0, _Thread, (void*) this, 0, &_d.id);
    }
    

    Jetzt wird auf das aktuelle Objekt verweisen und die Threadfunktion aufgerufen:

    static DWORD WINAPI	_Thread	(LPVOID Pointer)
    {
    	Test *This	= (Test*) Pointer;
    
    	This->_Thread_start();
    }
    

    In der _Thread_start() wird nun etwas mit den Variablen gemacht. Wenn ich nur ein Objekt erzeuge und den Thread starte, funktioniert dies wie erwähnt, fehlerfrei. (In meiner richtigen Klasse läuft der Thread, solange das Programm läuft)

    Erzeuge ich nun ein weiteres Objekt und starte den Thread mit dem neuem Objekt, haben die Variablen nicht mehr ihre richtigen Werte.

    Das Variablenstruct zu kopieren und im Thread zu benutzen funktioniert nur bedingt, da die Variablen während der Laufzeit ausgelesen werden und gleichzeitig durch den Thread verändert werden sollen. (Nein, es entsteht keine Überschneidung, der Thread
    "sagt" wenn eine weitere Funktion auf den Wert der Variable zugreifen darf.)

    Die neuen Objekte werden dynamisch erzeugt. Hierfür benutze ich in der Main eine Schleife mit einem Vector. Diese erzeugt bei Bedarf ein neues Objekt.

    vector<Test> test_obj;
    
    while(true)
    {
    	// Wenn benötigt mach neues Objekt (hier nicht relevant)
    	test_obj.push_back(Test());
    	test_obj[test_obj.size() - 1].start_thread();
    }
    

    Wenn noch Infos fehlen sollten, ergänze ich diese natürlich.

    Gruß Ombre



  • Ombre schrieb:

    Die neuen Objekte werden dynamisch erzeugt. Hierfür benutze ich in der Main eine Schleife mit einem Vector. Diese erzeugt bei Bedarf ein neues Objekt.

    Wenn der vector sich selbst vergrößern muss, werden die Objekte umkopiert. Damit werden die this-Zeiger, die sich die Threads gemerkt haben, ungültig.



  • Vollkommen logische Antwort ... erstelle ich normale Objekte funktioniert alles fehlerfrei. Durch den STL-Container gehts in die Hose.

    Ich habe leider durch google und Versuche keine Möglichkeit gefunden Objekte dynamisch zu erzeugen und zu lagern. Ich stehe grade extrem auf dem Schlauch und habe mich scheinbar in eine Richtung verbissen ... Wenn jemand einen Lösungsansatz hat bitte raus damit.

    Gruß
    Ombre



  • Wenn die maximale Anzahl der Objekte vorher feststeht, kannst du dem vector diese Anzahl mittels reserve mitteilen, dann braucht er sich nicht zu vergrößern.

    Oder du könntest std::list benutzen, dieser Container kopiert beim Hinzufügen nicht um.

    Wenn du unbedingt einen vector für den indexbasierten Zugriff brauchst, könntest auch einen vector von Smartpointern verwenden, oder die Objekte in eine list stecken, und die Adressen der Objekte in einen vector.



  • Danke dir für die Hilfe.
    Ich habe den einfachsten Weg genommen, da dieser im Moment vollkommen ausreichen ist. (ohne Prüf- und Sicherheitsroutinen)

    vector<Test> test_obj(50, Test());
    int zähler = 0;
    
    while(true)
        test_obj[++zähler].start_thread();
    

    Die anderen Möglichkeiten schaue ich mir auch noch an.


Log in to reply