Threading schaltet Debuglog zum nicht-dasein um?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Xaymar

ehemals "Cgamer"

Betreff: Threading schaltet Debuglog zum nicht-dasein um?

BeitragMo, März 07, 2011 0:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich erarbeite gerade mit Threads ein kleines Framework. Leider scheint Debuglog komplett außer Kraft zu sein. Warum?

Dazu kommt noch das das Programm stoppt.
Ich rufe das ungefähr so auf:
runGame
->OnInit
->Loop
->->OnDraw & OnUpdate
->OnDeinit

Nur erreicht er "Loop" nie. Es hält einfach an, als wären die Threads tot. Woran liegt das?

zpfGame.bmx
BlitzMax: [AUSKLAPPEN]
Type zpfGame
Field _UpdateTimer:TTimer, _DrawTimer:TTimer
Field _UpdateThread:TThread, _DrawThread:TThread
Field _PauseMutex:TMutex
Field _DebugMutex:TMutex

Field _DrawWait:Int, _UpdateWait:Int

Method OnInit() Abstract
Method OnUpdate() Abstract
Method OnDraw() Abstract
Method OnDeinit() Abstract

Method runGame(drawFPS:Int, updateFPS:Int)
'_UpdateTimer = CreateTimer(updateFPS)
'_DrawTimer = CreateTimer(drawFPS)
_PauseMutex = CreateMutex()
_DebugMutex = CreateMutex()

_DrawWait = 1000/drawFPS
_UpdateWait = 1000/updateFPS

_PauseMutex.Lock()
_DrawThread = CreateThread(___zpfDrawGame,Self)
_UpdateThread = CreateThread(___zpfUpdateGame,Self)
OnInit()
_PauseMutex.Unlock()
End Method
Method checkGame:Int()
Return _DrawThread.Running() + _UpdateThread.Running() *2
End Method
Method exitGame()
_PauseMutex.Lock()
OnDeinit()
_DrawThread.Detach()
_UpdateThread.Detach()
_PauseMutex.Unlock()
'_UpdateTimer = Null
'_DrawTimer = Null
_PauseMutex = Null
_DebugMutex = Null
End Method

Method LogDebug(message:String)
_DebugMutex.Lock()
DebugLog(message)
_DebugMutex.Unlock()
End Method
End Type

Function ___zpfUpdateGame:Object(Game:Object)
Local zGame:zpfGame = zpfGame(Game), lastUpdate:Int
Repeat
If zGame._PauseMutex.Lock() 'Check for Pause
lastUpdate = MilliSecs()

zGame._PauseMutex.Unlock()
zGame.OnUpdate()

While (MilliSecs()-lastUpdate) < zGame._UpdateWait;Wend
'zGame._UpdateTimer.Wait()
End If
Forever
End Function
Function ___zpfDrawGame:Object(Game:Object)
Local zGame:zpfGame = zpfGame(Game), lastDraw:Int
Repeat
If zGame._PauseMutex.Lock() 'Check for Pause
lastDraw = MilliSecs()

zGame._PauseMutex.Unlock()
zGame.OnDraw()

While (MilliSecs()-lastDraw) < zGame._DrawWait;Wend
'zGame._DrawTimer.Wait()
End If
Forever
End Function

zpfGameText.bmx
BlitzMax: [AUSKLAPPEN]
'Include Base Game
Include "../../zpfGame.bmx"

Type MyGame Extends zpfGame
Field _Graphics:TGraphics
Method New()
runGame(60,100)
While checkGame() <> 0
DebugLog "looooop"
Wend
exitGame()
End Method

Method OnInit()
_Graphics = Graphics(800,600,0)
Cls
SetColor(255,255,255)
DrawText("Hello World",0,0)
DebugLog "text"
Flip
End Method
Method OnUpdate()
If KeyHit(KEY_ESCAPE)
exitGame()
End If
End Method
Method OnDraw()
SetGraphics(_Graphics)
Cls
DrawRect 10,10,100,100
Flip
End Method
Method OnDeinit()
SetGraphics(_Graphics)
EndGraphics
End Method
End Type

Local Timer:TTimer = CreateTimer(10)
Local Game:MyGame = New MyGame
'Game.runGame(60,100)
'Repeat
' WaitTimer(Timer)
'Until Game.checkGame() <> 3
'If Game.checkGame() > 0 Then Game.exitGame()
Warbseite

mpmxyz

BeitragMo, März 07, 2011 12:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Als Erstes ist mir ein enormer Leistungsverbrauch aufgefallen:
BlitzMax: [AUSKLAPPEN]
While (MilliSecs()-lastDraw) < zGame._DrawWait;Wend

Vielleicht hat es damit etwas zu tun.
Was wird eigentlich hier abgesichert? Eine lokale Variable? Wink
BlitzMax: [AUSKLAPPEN]
		If zGame._PauseMutex.Lock()	'Check for Pause
lastUpdate = MilliSecs()
zGame._PauseMutex.Unlock()

Nun zum eigentlichen Problem:
Debuglog scheint sogar threadsicher zu sein.
BlitzMax: [AUSKLAPPEN]
SuperStrict
Framework brl.Threads

CreateThread(func,Null)
For Local i:Int=0 Until 100
DebugLog "Debug main"
Next
Delay 1000 'Damit sich das Programm nicht gleich beendet...

Function func:Object(obj:Object)
For Local i:Int=0 Until 100
DebugLog "Debug Thread"
Next
EndFunction

-> Der Fehler liegt woanders.
Teste deinen Code mal mit DebugStop durch!
Ich habe es gemacht.
Mir ist aufgefallen, dass du "If zGame._PauseMutex.Lock()" geschrieben hast.
Die Lock-Methode gibt aber keinen Wert zurück, da sie immer funktioniert!
(Nur die TryLock-Methode gibt zurück, ob der Zugriff möglich ist.)
mfG
mpmxyz
PS: Grafikoperationen sollten alle im gleichen Thread stattfinden. Frage mich aber nicht mehr nach dem Grund. Events mögen es auch nicht, wenn sie außerhalb des Mainthreads benutzt werden.
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Lord Stweccys

BeitragMo, März 07, 2011 12:29
Antworten mit Zitat
Benutzer-Profile anzeigen
mpmxyz hat Folgendes geschrieben:
Grafikoperationen sollten alle im gleichen Thread stattfinden.


Ich habe die Erfahrung gemacht, dass Grafikoperationen generell nur im Hauptprogramm funktionieren.
Sobald, ich alles in einen Thread ausgelagert hab, blieb das Bild schwarz...

mpmxyz

BeitragMo, März 07, 2011 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe das Beispielprogramm von Xaymar hier so geändert, dass auch im Zeichenthread gezeichnet werden konnte. (->alles, was mit Grafik zu tun hat, in den entsprechenden Thread)
Die Benutzereingaben funktionierten aber (noch) nicht.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Xaymar

ehemals "Cgamer"

BeitragMo, März 07, 2011 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
mpm:
1-Timer gehen ja nicht, was soll ich da sonst nehmen? Delay?
2-Da wird nichts abgesichert, da stelle ich nur die Threads mit auf Pause, da Blitzmax ja kein PauseThread besitzt. Oder?
3-Warum gibt die Lock() methode nichts zurück? Ist das nicht i.e. dieselbe funktion wie LockMutex() in der WinAPI?
4-Ich werde es mal mit DebugStop durchgehen...

Aber wird wohl bei Grafikausgabe daraus hinauslaufen eine WorkerQueue zu basteln. Das wird ein Spaß...

PS: Ich denke das läuft auf die Struktur hinaus wie BlitzMax aufgebaut ist. Da threading ja später hinzugekommen ist, muss man halt sich selber sogenannte WorkerQueues dafür erstellen, die halt die Aufgaben erledigen und ggf Threads usw wecken und töten.
Warbseite

mpmxyz

BeitragMo, März 07, 2011 16:14
Antworten mit Zitat
Benutzer-Profile anzeigen
1. "Delay 1" würde den Computer schon gut entlasten.
2. Du möchtest damit nur den Thread pausieren?
3. BlitzMax: [AUSKLAPPEN]
	Method Lock()
Assert _handle
threads_LockMutex _handle
End Method

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group