Thread (Wie bekomme ich das hin?)
-
Hallo an alle.
Kann mir einer sagen wie Threads funktionieren?
Ich habe ein konkretes Problem!Ich habe eine "*.lib" erstellt in der es zwei klassen gibt.
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.So. Jetzt an die spezies unter euch. Wie mach ich das?
Derzeit siht meine Funktion so aus!
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;}
-
Ich verweise dich einfach mal auf den folgenden link, da steht eigentlich alles beschrieben: http://www.henkessoft.de/mfc_einsteigerbuch_kapitel17.htm
-
hier der beispielcode aus meiner http dll
//threadhandel HANDLE hFileGrabber=NULL; //thread erstellen if(NULL==(hFileGrabber=CreateThread(NULL,CurrentFileSize*5,GrabHtmlFile,(LPVOID)this,NULL,NULL))) return SaveLastError(::GetLastError(),"Fehler beim Aufsetzen des Download Threads!"); //threadfunc DWORD WINAPI GrabHtmlFile(LPVOID Control) { return (DWORD)Control; } //schließen if(hFileGrabber) { if(!CloseHandle(hFileGrabber)) { return SaveLastError(::GetLastError(),"Fehler beim schließen des Threads!"); } hFileGrabber=NULL; }
-
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