Klassen-Funktion im Thread aufrufen
-
Hi,
ich will aus einer Thread-Funktion eine Klassenfunktion aufrufen.
Leider klappt das nicht ganz, weil beim Aufruf der Klassenfunktion manchmal das
Programm abstürzt oder die Klassenfunktion falsch ausgeführt wird.Der Code sieht wie folgt aus:
clXyCity XyCity; static DWORD WINAPI threadFunc(LPVOID data) { // KlassenFunktion XyCity.LoadObjects(-1); } CreateThread(NULL, 0, threadFunc, NULL, 0, 0);Hab auch schon probiert die KlassenFunktion über einen Pointer aufzurufen, leider erfolglos.
Mfg, Pk3

-
Ups... Sorry...
Das war wohl nicht passend
-
Abgesehen dass es schrecklich ist, die globale Variable zu haben...
Wann rufst Du CreateThread(..) auf? Ist da dein Objekt schon erzeugt?
Und CloseHandle(..) nach dem CreateThread(..) nicht vergessen.
Ausserdem: Warum machst Du nicht im Konstruktor deiner Klasse einen eigenen Thread? Sozusagen ein aktives Objekt?
-
Pk3 schrieb:
weil beim Aufruf der Klassenfunktion manchmal das
Programm abstürztDas liegt dann wohl am Programm. Rufst du Funktionen von XyCity aus mehreren Threads auf?
oder die Klassenfunktion falsch ausgeführt wird.
Falsch? Wie "falsch"?
P.S.: Zeilenumbruch kann das Forum auch allein, ohne deine Hilfe.
-
@theta
CreateThread wird in der Main - Funktion aufgerufen und das Objekt ist da schon erzeugt bevor der Thread startet. Hab jetzt auch CloseHandle danach gemacht.Ausserdem: Warum machst Du nicht im Konstruktor deiner Klasse einen eigenen Thread? Sozusagen ein aktives Objekt?
Koennte ich auch machen, aber so muss es doch auch funktionieren, oder
?@Nukularfüsiker
Ne, die Funktion wird nur in diesen einen Thread aufgerufen. Und das es abstürtzt, liegt definitiv am Thread. Habs ausprobiert in dem ich den Aufruf der Klassenfunktion in die Mainfunktion gemacht habe, da kam kein crash oder "Fehler". Mit den Fehlern mein ich, das der da keine Texturen für die Objekte ladet, sehr komisch, keine Ahnung was da genau net richtig funktioniert.P.S.: Zeilenumbruch kann das Forum auch allein, ohne deine Hilfe.
Ja dumme Angewohnheit, sorry :D.
Mfg, Pk3
-
Was sagt denn der Debugger?
-
Pk3 schrieb:
Ne, die Funktion wird nur in diesen einen Thread aufgerufen.
Es ging aber nicht (nur) um diese Funktion, sondern das Objekt! Wenn du auf ein Objekt lesend zugreifst, während ein anderer Thread zeitgleich schreibend darauf zugreift, hast du gute Chancen, dass der lesende Müll bekommt. Oder lass mehrere gleichzeitig schreiben

(schreiben == Objekt verändern, lesen == Werte beim Objekt erfragen).
Lösung: Zugriffe mit Mutexen synchronisieren.
-
Auf das Objekt wird nirgentwo zugegriffen auser im Thread.
Hier mal zur Verdeutlichung:int texId; class clXyCity { public: stPlayer Player[MAX_PLAYERS]; long myBrushId; bool bRefreshMyEntity; void LoadObjects(int sec) { .... Code ... int texId=Render.LoadTexture(filename); printf("[THREAD] Texture-Id: %i, Texture-Name: %s\n", texId, Render.Image[texId].name); ... Code ... } ... }; ... clXyCity XyCity; static DWORD WINAPI threadFunc(LPVOID data) { // KlassenFunktion XyCity.LoadObjects(-1); } int main() { texId = -2; HANDLE hThrd=CreateThread(NULL, 0, threadFunc, NULL, 0, 0); CloseHandle(hThrd); while(1) { // Warten bis texId nicht mehr "-2" ist (bis die Texture geladen wurde) if(texId != -2) { // Texture - Infos ausgeben printf("[MAIN] Texture-Id: %i, Texture-Name: %s\n", texId, Render.Image[texId].name); texId=-2; } Sleep(5); } }Es scheint so, als ob der Fehler be OpenGL liegt, weil alle Textur - Daten in der Main - Funktion lesbar sind, auch die Pixeldaten.
Hier die LoadTexture - Funktion:
int clRender::LoadTexture(char *strFile) { int slotId; char typ[256]; slotId = GetFreeTextureSlot(); if(slotId != -1) { memset(typ, 0, 256); File.GetFileTyp(strFile, typ); if(strcmp(typ, ".bmp") == 0) { if(File.Exist(strFile) == true) { Image[slotId].auxTex=auxDIBImageLoad(strFile); } else { return -1; } if(Image[slotId].auxTex != NULL) { Image[slotId].lock = 1; strcpy(Image[slotId].name, strFile); glGenTextures(1, &Image[slotId].tex); glBindTexture(GL_TEXTURE_2D, Image[slotId].tex); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Image[slotId].auxTex->sizeX, Image[slotId].auxTex->sizeY, GL_RGB, GL_UNSIGNED_BYTE, Image[slotId].auxTex->data); } else { return -1; } } } return slotId; }Wenn die Textur jetzt auf ein Objekt gelegt wird, ist das Objekt weiß, also keine Textur. Kann es sein, das einer dieser OpenGL - Funktionen im Thread nicht funktionieren? Oder hab ich da was falsch gemacht?
-
Pk3 schrieb:
Kann es sein, das einer dieser OpenGL - Funktionen im Thread nicht funktionieren?
Das stünde dann in der Dokumentation, die du ja bestimmt gelesen hast.
Oder hab ich da was falsch gemacht?
Bezüglich deines Problems: Ein paar Fehlerprüfungen im Code könnten nützlich sein.
Weißt du was ein Debugger ist?Ansonsten: hässlichster C-mit-Klassen-Code seit langem.
-
Du benutzt Render in zwei Threads, ohne die Zugriffe zu synchronisieren. Wann und wo das globale texId gesetzt wird, kann ich deinem Code nicht entnehmen (in LoadObjects gibt's eine lokal definierte Version), aber auch der Zugriff ist wohl nicht synchronisiert.
Lars
-
Das Problem lag allein an einer OpenGL - Funktion die nicht threadsicher war.
Habs geloest in dem ich die OpenGL - Funktion in die Main - Funktion gemacht habe und diese über eine Variable (BOOL) über den Thread aurufen kann.Trotzdem vielen Danke ;)!
-
Pk3 schrieb:
Das Problem lag allein an einer OpenGL - Funktion die nicht threadsicher war.
Habs geloest in dem ich die OpenGL - Funktion in die Main - Funktion gemacht habe und diese über eine Variable (BOOL) über den Thread aurufen kann.Ich verstehe deine Erklärung nicht genau (sind das Gedanken- oder Bindestriche?), aber zur Threadsynchronisation benutzt man Mutexes, Semaphoren oder Critical Sections. Anderes Gefrickel wird dir früher oder später um die Ohren fliegen. Garantiert.