Thread (Wie bekomme ich das hin?)
-
Hi
haedfinger schrieb:
Kann mir einer sagen wie Threads funktionieren?
Du kannst entweder eine Klasse von CWinThread ableiten oder du erstellst eine Threadfunktion nach dem Schema: UINT ThreadFunc(LPVOID)
haedfinger schrieb:
auf die eine (CInteraktion) kann von außen zugegriffen werden (int leseStatus())diese wiederum soll eine funktion in der zweiten Klasse (CAbfrage) starten. Bei dieser Funktion soll ein Thread gestartet werden, der mir permanent ein array (int a[32]) neu beschreibt.
Hab ich nicht so ganz verstanden. Meinst du sowas:
CInteraktion::leseStatus ruft CAbfrage::Funktion auf CAbfrage::Funktion startet einen neuen Thread?int CInteraktion::LesePermanent() { CAbfrage bla; m_pWatchThread = AfxBeginThread( (AFX_THREADPROC)bla.Watch, (UNIT) this, THREAD_PRIORITY_NORMAL, 0,CREATE_SUSPENDED ); m_pWatchThread->ResumeThread(); return 1; } // Folgende Funktion soll ständig (als Thread) laufen. UNIT CAbfrage::Watch(LPVOID pParam) { CInteraktion versuch; do { int i=0; for(i=0;i<32;i++) versuch.m_a[i]= 0 + ( rand() % (1 - 0 + 1)); Sleep(100); } while (TRUE); return 0;}Achso, der Quellcode verdeutlicht dein Problem.
Um eine Methode als Threadfunktion nutzen zu können, muss sie mit static deklariert sein. Leider kannst du dann auch nur auf statische Methoden/Membervariablen zugreifen.
Eine (unsaubere) Möglichkeit um
in der Threadfunktion auf das CInteraktion und CAbfrage Objekt gleichzeitig zugreifen zu können wäre eine Struktur zu verwenden:typedef struct ThreadParam_ { CInteraktion* pInteraktion; CAbfrage* pAbfrage; } ThreadParam; int CInteraktion::LesePermanent() { CAbfrage* bla = new CAbfrage; // CAbfrageobjekt erstellen ThreadParam param; param.pInteraktion = this; param.pAbfrage = bla; m_pWatchThread = AfxBeginThread( (AFX_THREADPROC)CAbfrage::Watch, param, THREAD_PRIORITY_NORMAL, 0,CREATE_SUSPENDED ); m_pWatchThread->ResumeThread(); return 1; } // Folgende Funktion soll ständig (als Thread) laufen. static UNIT CAbfrage::Watch(LPVOID pParam) { ThreadParam Param = (ThreadParam) pParam; do { int i=0; for(i=0;i<32;i++) Param->pInteraktion.m_a[i]= 0 + ( rand() % (1 - 0 + 1)); Sleep(100); } while (TRUE); return 0;}Allerdings musst du dich darum kümmern, dass das CAbfrage Objekt noch irgendwo gelöscht wird.
Ich hoffe ich habe dich richtig verstanden

Grüße Rapha
-
Hey Rapha.
Danke.
Als ich mir das Tutorial durchgelesen hab, bekam ich auch mit, das meine Funktion "static" sein muß. Wie blöd!!!Das mit der Struktur ist eine coole Lösung.
Ich habe viel gebastelt, aber es nicht hinbekommen.-----
Habe es jetzt versucht, aber bekomme noch nen Fehler. (Natürlich wieder an meiner lieblingsstelle.)Fehler: Durch keine der 2 Ueberladungen kann Parameter 2 vom Typ 'struct ThreadParam_' konvertiert werden
m_pWatchThread = AfxBeginThread ( (AFX_THREADPROC)CIOAbfrage::WatchIO, ==> param, THREAD_PRIORITY_NORMAL, ==> 0,CREATE_SUSPENDED ); pThread->ResumeThread();==> = In diesen Zeile ist der Fehler
(Immer das gleiche)Ach und warum muß ich das CAbfrage Objekt löschen?
Meinst du sowas wie: delete Param?
-
haedfinger schrieb:
m_pWatchThread = AfxBeginThread ( (AFX_THREADPROC)CIOAbfrage::WatchIO, ==> param, THREAD_PRIORITY_NORMAL, ==> 0,CREATE_SUSPENDED ); pThread->ResumeThread();==> = In diesen Zeile ist der Fehler
Hm, versuchs mal mit
m_pWatchThread = AfxBeginThread( (AFX_THREADPROC)CAbfrage::Watch, (LPVOID) param, THREAD_PRIORITY_NORMAL, 0,CREATE_SUSPENDED );haedfinger schrieb:
Ach und warum muß ich das CAbfrage Objekt löschen?
Meinst du sowas wie: delete Param?Du hast doch mit
CAbfrage* bla = new CAbfrage; // CAbfrageobjekt erstellenein Objekt erzeugt. Das musst du dann auch löschen (am Besten du machst ne Membervariable draus, erstellst sie im Konstruktor und löschst sie im Destruktor)
Grüße Rapha
-
m_pWatchThread = AfxBeginThread( (AFX_THREADPROC)CAbfrage::Watch, (LPVOID) param, THREAD_PRIORITY_NORMAL, 0,CREATE_SUSPENDED );Das gibt dann diesen Fehler.
error C2440: 'type cast' : 'struct ThreadParam_' kann nicht in 'void *' konvertiert werden
Ich bin echt am verzweifeln.
Warum wird es einem so schwer gemacht einen Thread zu erstellen?------
Ich dachte ein Objekt wird sowieso gelöscht,wenn der destruktor aufgerufen wird.
Außerdem komm ich nicht klar mit der membervariable.
Bei einem Dialog war es ja recht einfach.m_testDlg.Create(IDD_TEST, this); // dann irgendwann m_testDlg.EndDialog(IDOK); m_testDlg.DestroyWindow(); delete m_testDlg;und fertig.
Aber hier ist dasnicht so einfach, oder?
-
m_pWatchThread = AfxBeginThread( (AFX_THREADPROC)CAbfrage::Watch,
(LPVOID) ¶m,
THREAD_PRIORITY_NORMAL,
0,CREATE_SUSPENDED );und gut is

-
Nur mal ein kurzer Einwurf. Wenn ich einen Thread erstelle, benutze ich _beginthreadex.
Schon mal damit probiert?
-
@ sovok
Ja. Hab ich auch schon versucht. Dann wiederum gibt es hier einen Fehler...UINT CAbfrage::Watch( LPVOID pParam ) { ==> ThreadParam Param = (ThreadParam) pParam; //... for(int i=0;i<32;i++) Param->pInteraktion.m_iAktuell[i] = 1 ;//0 + ( rand() % (1 - 0 + 1)); //...... und zwar diesen. ==>
error C2440: 'type cast' : 'void *' kann nicht in 'struct ThreadParam_' konvertiert werdenWenn ich das jetzt auch verändere in:
UINT CIOAbfrage::WatchIO( LPVOID pParam ) { ThreadParam* Param = (ThreadParam*) pParam; for(int i=0;i<32;i++) Param->pInteraktion->m_iAktuell[i] = 1 ;//0 + ( rand() % (1 - 0 + 1));Dann hab ich zwar keinen einzigen Fehler mehr, aber ich bekomme einen ganz fiesen Fehler beim Ausführen.
-
natürlich bekommst du einen fiesen fehler beim ausführen
der code is aber richtigThreadParam *Param = (ThreadParam*) pParam; //threadfunktion
zeigt auf
ThreadParam param; //LesePermanent() funktionwas passiert mit
ThreadParam param; //LesePermanent() funktion
wenn du die funktion fertig durchlaufen hast?für ne richtige antwort bekommst du die lösung

-
Mit durchlaufen der Funktion endet mein Gültigkeitsbereich!
??????
-
richtig
das bedeutet
ThreadParam param; //LesePermanent() funktion
wird gelöscht und
ThreadParam *Param = (ThreadParam*) pParam; //threadfunktion
zeigt auf ein objekt das nicht mehr existiertlösung: mach ThreadParam param; zu ner membervariable von CAbfrage
-
Ich bin ja glücklich, das ich (mit deiner hilfe) gesehen hab das der Gültigkeitsbereich endet, aber jetzt steh ich auf dem Schlauch.
Hab ich das richtig verstanden?
Ich soll im CAbfrage eine membervariable z.B. m_tp vom typ ThreadParam_ anlegen?
Und dann?
-
ne natürlich in der CInteraktion, sorry
-
hab ich gemacht. Wie es aussieht aber mal zur abwechslung Falsch.

muß doch nur die Variable "m_tp" da einsetzen wo vorher param stand, oder.Jedenfals ging es so nicht und ich habe es wieder zurückgeändert, wobei ich jetzt angeblich einen Fehler in der Struktur habe und eine Neudefinition und noch 17 weitere Fehler.
Muß erstmal schauen, woran das liegt.
-
warum ging es so nich?
-
Ich habe die Struktur
typedef struct ThreadParam_ { CInteraktion* pInteraktion; CIOAbfrage* pAbfrage; }ThreadParam;In eine Extra Haeder Datei. "Struktur.h"
Diese habe ich dann jeweils in "Interaktion.cpp" und in der "Abfrage.cpp" eingebunden.
Aus irgendeinen Grund stand das aufeinmal in der "Abfrage.h".#include "Struktur.h" // Hinzugefügt von der KlassenansichtDas gab nen crash.
-----
Was soll ich nun machen? die Membervariable kann ich knicken, weil die Struktur bis dahin unbekannt ist.
Und wenn ich si vorher einbinde gibt es wieder nen crash
-
ich benutz keine structs
also mach mal aus der struct ne klasseclass ThreadParam
{
public:
CInteraktion* pInteraktion;
CIOAbfrage* pAbfrage;
};binde den header in die cpps ein und in den anderen headern schreibst du nur class ThreadParam;
#ifndef
#define#endif
nich vergessendann probiers nochmal
-
(Schade das du keine Strukturen nutzt. Ich fand den Ansatz von Rapha gut.)
Alles gemacht! jetzt ist nurnoch die Klasse nicht definiert.
error C2079: 'm_tp' verwendet undefiniertes class 'ThreadParam'
habe aber "class ThreadParam;" vor die Klasse geschrieben.
Liegt es an der Klasse selbst? Wußte nicht was ich hier schreiben sollte:#ifndef ...
#define ...#endif
Bei mir sieht es so aus. (Struktur.h)
#ifndef ThreadParam #define run class ThreadParam { public: CInteraktion* pInteraktion; CIOAbfrage* pAbfrage; }; #endif
-
#ifndef _H__ThreadParam__H_ //falls dieser header noch nich eingebunden wurde
#define _H__ThreadParam__H_ //binde ihn jetzt einclass ThreadParam
{
public:
CInteraktion* pInteraktion;
CIOAbfrage* pAbfrage;
};#endif //andernfalls überspringe ihn
wenn du das nich machst kann es sein, dass du den mehrfachdeklaration-fehler bekommst
ausserdem musst du den header mit #include in die cpp files einbinden
bzgl. error C2079: 'm_tp' verwendet undefiniertes class 'ThreadParam'
d.h. dass du auf membervariablen oder memberfunktionen zugegriffen hast ohne vorher den header einzubindenclass cBlah;
cBlah einBlah;// OK
einBlah.func();//Fehler
#include "cBlah.h"
einBlah.func();//OK
-
In die beiden cpp's hab ich sie schon eingebunden (Interaktion.cpp , Abfrage.cpp)
Soll es auch in die StdAfx.cpp ?
Außerdem hab ich wie du es sagtest "class ThreadParam;" direkt vor die Klassendefinitionen in (Interaktion.h , Abfrage.h) geschrieben.
Gibt natürlich auch einen Fehler.error C2079: 'm_tp' verwendet undefiniertes class 'ThreadParam'
Ich glaub wenn das gelöst ist sollte es gehen.
-
ne in die StdAfx muss es nich
was passiert wenn du statt "class ThreadParam;" den header einbindest?