Threaded Blitz3D

Übersicht BlitzBasic DLLs und Userlibs

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

Silver_Knee

Betreff: Threaded Blitz3D

BeitragSo, Nov 01, 2009 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
~AUFSPALTUNG~

Auf wunsch des Erstellers von Funktionszeiger für Blitz3D abgeschnipselt
Für diese Funktion wird die DLL&Decls von Noobody aus oben genanntem Thread benötigt (Direktlink)
mfG Holzchopf


So als weitere sinnvolle Anwendung dieser Funktionszeiger, möchte ich euch mal Threaded Blitz3D zeigen:

Für die, die es nicht wissen: Kurz erklärt, ist ein Thread eine Funktion, die im hintergrund, paralel zum hauptprogramm läuft.

In diesem Beispiel werden im Hintergrund Bilder geladen. Damit es eindrucksvoller wird könnt ihr ja ordner mit besonders großen und vielen bildern nehmen, sodass Loadimage immer langsamer wird. wollt ihr nur schnell testen, gebt nichts ein, dann nehmt ihr den Ordner Eigene Bilder (oder wie er auch immer bei euch heißen mag).

Zusätzliche Userlibs:
Code: [AUSKLAPPEN]

.lib "kernel32.dll"
CreateThread%(lpThreadAttributes*,dwStackSize%,lpStartAddress%,lpParameter%,dwCreationFlags%,lpThreadId*)
CloseHandle(handle%)


Beispiel Code:
Code: [AUSKLAPPEN]
Local tmp,lblLoadImages,temp$,thread
Dim Images(0)
Global count,max,dir,proginit=1

Graphics 800,600,32,2
SetBuffer BackBuffer()

tmp=GetInstructionPointer()
If proginit=1
   lblLoadImages=tmp
Else
   For count=1 To max
      Images(count)=LoadImage(NextFile(dir))
   Next
   
   Return
EndIf

proginit=0

Repeat
   temp=Input("Gebe einen Ordner mit Bildern an:")
   dir=ReadDir(temp)
   If dir=0 Or temp=""
      temp=GetEnv("HOMEPATH")+"\Pictures"
      dir=ReadDir(temp)
      If dir=0
         temp=GetEnv("HOMEPATH")+"\Bilder"
         dir=ReadDir(temp)
         If dir=0
            temp=GetEnv("HOMEPATH")+"\My Pictures"
            dir=ReadDir(temp)
            If dir=0
               temp=GetEnv("HOMEPATH")+"\Eigene Bilder"
               dir=ReadDir(temp)
            EndIf
         EndIf
      EndIf
   EndIf
Until dir<>0

ChangeDir temp

Repeat
   temp=NextFile(dir)
   max=max+1
Until temp=""

CloseDir dir
dir=ReadDir(".")

Dim Images(max)

thread=RunThread(lblLoadImages)

Repeat
   tmp=(tmp+1) Mod 360
   
   Oval 400+Sin(tmp)*250-5,300+Cos(tmp)*250-5,10,10
   
   Color 255,255,255
   Text 400,280,"Loading... ["+count+"/"+max+"]",1
   
   Color 255,0,0
   Rect 300,320,200,10
   
   Color 0,255,0
   Rect 300,320,count*200/max,10
   
   Color 255,255,255
   Rect 300,320,200,10,0
   
   Flip
   Cls
Until count=>max

CloseHandle thread

count=0
Repeat
   While Images(count)=0
      count=(count+1) Mod max
   Wend
   
   DrawImage Images(count),0,0
   Flip
   Cls
   WaitKey
   count=(count+1) Mod max
Forever

Function RunThread(pointer)
   Local s.SECURITY_ATTRIBUTES,ret
   
   s=New SECURITY_ATTRIBUTES
   s\nLength = 8;länge wird korrekt gesetzt: 2 integer= 8 byte
   s\lpSecurityDescriptor=Null;Keine besonderen Sicheheitsmerkmale
   s\bInheritHandle=0;vererbung abgeschaltet (für was auch immer^^)
   
   Local bank=CreateBank();Wird genutzt als geforderter Pointer hat aber keine Wirkung
   
   ret=CreateThread(s,0,pointer,bank,0,bank)
   
   Delete s
   Return ret
End Function

;Von der WINAPI geforderte Struktur
Type SECURITY_ATTRIBUTES
   Field nLength
   Field lpSecurityDescriptor.SECURITY_ATTRIBUTES
   Field bInheritHandle
End Type


Dabei ist einiges zu beachten:


  • Innerhalb der Funktion darf nur auf globale und dims zugegriffen werden, da die "lokalen" die man dort antrifft eigentlich teil des "<main program>" sind. die variablennamen zeigen zu der zeit auf andere stellen im Speicher und könnten Probleme bereiten, wenn man sie versucht zu ändern. Benötigt man lokale Variablen muss man eine Globale bank machen, die ja dann nach belieben resizet werden und verschiedene Werte haben kann. Auf Types muss man verzichten oder globale Zugriffsvariablen nutzen.
  • Beim starten mehrer Threads, sowie beim Hauptprogramm ist zu beachten, dass diese globale eben gleichzeitig von allen genutzt werden. Das kann wie im Beispiel nützlich sein (count wird im hintergrund hochgezählt und bestimmt so das Ende des Loading-Bilsdchirms) aber man kann sich natürlich auch im weg stehen (lokale variablen etc...)
  • Der Grafikbuffer sollte nur von einem Thread gleichzeitig benutzt werden. greifen 2 oder mehr Threads bzw das hauptprogramm und ein thread gleichzeitig auf die grafikoberfläche zu, kommt es unweigerlich zum flackern. [evtl DXBedingt, könnte aber auch daran liegen, dass 2 unterschiedliche schleifen wohl nie genau gleich schnell sind] es ist hier eher angebracht alle zeichenaufträge mittels globals an eine hauptschleife zu schicken.
  • Während ein thread am Laufen ist, erzeugt ein klick auf X eine fehlermeldung sowie das unverzügliche, nicht auf ein OK wartende ende des prozesses. Das liegt wahrscheinlich daran, dass die Beendigungsfunktion von blitz eben nicht weiß, dass der thread am laufen ist.


Außerdem fallen mir jetzt ganz viele einsatzgebiete ein wo immer ein lpFunctionPointer gefordert wird und es mit blitz nie ging.

~EDITIERT~

Aufgrund der Aufteilung musste noch der Link zur Lib angegeben werden.
Holzchopf
  • Zuletzt bearbeitet von Silver_Knee am So, Nov 01, 2009 20:57, insgesamt 2-mal bearbeitet

ZaP

BeitragSo, Nov 01, 2009 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Beeindruckend! Das ist sehr nützlich für animierte Ladebildschirme Very Happy
Nein ehrlich, sehr gute Arbeit habt ihr da geleistet.
Starfare: Worklog, Website (download)

Xaymar

ehemals "Cgamer"

BeitragSo, Nov 01, 2009 20:42
Antworten mit Zitat
Benutzer-Profile anzeigen
2 wörter:
EPIC WIN

Die Lib kommt mir ziemlich gelegen zu meinem nächsten Projekt:D

Edit: Ich werd aus dem Beispiel nicht wirklich schlau. Was muss ich tun wenn ich ne Funktion als Thread starten will?
Warbseite

FireballFlame

BeitragSo, Nov 01, 2009 22:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Erstmal: sehr sehr geil!!

Jetzt die schlechte Nachricht: wenn ich einen größeren Bilderordner angebe, stürzt mir das Programm irgendwann beim Laden ab. Mit kleineren gehts.

EDIT: Ich hab ein bisschen damit rumgespielt und verstehe auch noch nicht so ganz, nach welchem Muster der Fehler beim Beenden kommt und wie das ganze funktioniert. Was macht das Return? Was macht CloseHandle? Und wann müssen die beiden jeweils aufgerufen werden?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

mpmxyz

BeitragSo, Nov 01, 2009 23:02
Antworten mit Zitat
Benutzer-Profile anzeigen
An sich ist das eine tolle Sache, aber es sollten noch Fehler entfernt werden:
Beim Betrachten der Bilder kam irgendwann eine Meldung mit "blitzcc.exe hat einen Fehler festgestellt und muss beendet werden"...
Da ich aber bis jetzt noch keinen sinnvollen Verwendungszweck für meine Projekte gefunden habe, ist das für mich persönlich nicht weiter schlimm.
mfG
mpmxyz

P.S.: Jetzt kann ich mit wilden Pointern herumschießen... Wink
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

DAK

BeitragSo, Nov 01, 2009 23:06
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm... im mom is das ding ungefähr so verbuggt wie das in bmax (mark, beweg deinen faulen hintern und mach was! Wink ), aber s is imho (neben den funktionspointern) so ziemlich der atemberaubendste hack von b3d...

ich hab in der tat auch schon an sowas gedacht, aber nicht umgesetzt, da mir die windows-createthreadfunktion doch entwas zu komplex zu verstehen war, dafür dass ich eh kein b3d mehr verwend.
Gewinner der 6. und der 68. BlitzCodeCompo

Silver_Knee

BeitragMo, Nov 02, 2009 0:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Return ist eine Technik der Funktionspointer und Bezeichnet das Ende der Funktion aus Sicht der Funktion.

CloseHandle gibt den Speicher der CreateThreat Funktion wieder frei und muss(!) demnach nach dem Return Statt finden [Schreckliche dinge werden geschehen wenn man es gar innerhalb des threats vor return macht]. Man muss das machen, da man über die API den gleichen Thread nocheinmal starten könnte. Außerdem wird damit der Fehler beim Beenden via X-Button beseitigt.

Für einfache Dinge reicht es. Je mehr dateien du lädtst desto größer ist die chanse dass du auf den arbeitsspeicher von count genau dann zugreifst wenn er beschrieben wir, was evtl zu so einem Absturz beitragen könnte. evtl hilft hier das erstellen von "Event-Types" um das risiko zu minimieren. Oder vllt auch banks?

Mutexe hab ich Chat aufgefasst würden helfen. Die kann man soweit ich weiß nutzen (foren Suche: Blitz 2 mal starten).

FireballFlame

BeitragMo, Nov 02, 2009 0:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Silver_Knee hat Folgendes geschrieben:
Mutexe hab ich Chat aufgefasst würden helfen. Die kann man soweit ich weiß nutzen (foren Suche: Blitz 2 mal starten).
Die Forensuche liefert zu diesem Suchbegiff nichts, was mit dem Thema zu tun hat. Was meinst du?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Silver_Knee

BeitragMo, Nov 02, 2009 0:57
Antworten mit Zitat
Benutzer-Profile anzeigen
ahh. hat doch etwas gebraucht aber es hatte was mit dem Anwendungen 2 mal starten problem zu tun:

https://www.blitzforum.de/foru...php?t=5436

FireballFlame

BeitragMo, Nov 02, 2009 2:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Der verlinkte Thread hilft mir nicht so ganz weiter; schon wenn man den Beispielcode einfach 2mal hintereinanderkopiert, merkt man, dass ReleaseMutex(hMutex) den Mutex wohl nicht richtig entfernt, denn es kommt die "Anwendung läuft bereits"-Fehlermeldung.
Man bräuchte zumindest die Möglichkeit, einen erstellten Mutex so wie in BlitzMax mit LockMutex, TryLockMutex und UnlockMutex zu sperren/freizugeben.
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Silver_Knee

BeitragMo, Nov 02, 2009 9:00
Antworten mit Zitat
Benutzer-Profile anzeigen
ja du kannst als name was anderes als blitz.. angeben dann wird das ding auch nicht von blitz selbst initiiert sondern von dir.

FireballFlame

BeitragMo, Nov 02, 2009 14:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ändert nichts an dem Problem. Das 2. CreateMutex produziert trotzdem einen Fehler, wenn ich mehrmals im Programm den selben Namen nehme.
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Pummelie

BeitragMo, Nov 02, 2009 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Super Sache die ihr da gemacht habt, das macht BB gleich viel Umfassender, und für jeden der es noch nicht hat interraster Exclamation
It's done when it's done.

Silver_Knee

BeitragMo, Nov 02, 2009 17:33
Antworten mit Zitat
Benutzer-Profile anzeigen
@mutex soll es ja auch. das ist ja der witz: du erstellst ein mutex und wenn dus niochmal machen willst dann gehts halt nicht so kannst du arbeiten an etwas zB sperren

FireballFlame

BeitragMo, Nov 02, 2009 21:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Und was nützt mir das dann für meine Variablen, wenn ich es nicht auch wieder entsperren kann?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Xaymar

ehemals "Cgamer"

BeitragMo, Nov 02, 2009 21:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Du kannst es entsperren, nur ist das ein weiterer hack für B3D, der auch gerne mal einfach so crasht.

int = TryLockMutex(hMutex)
int = LockMutex(hMutex)
int = UnlockMutex(hMutex)
Warbseite

FireballFlame

BeitragDi, Nov 03, 2009 15:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Und woher krieg ich den?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Xaymar

ehemals "Cgamer"

BeitragDi, Nov 03, 2009 16:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Kriegen kannst du ihn leider nicht mehr :-/
Sind auf jedenfall winApi befehle, und sollten eigentlich nur 1, 2 parameter haben(ich kenn die nur mit einem)
Warbseite

FireballFlame

BeitragMi, Nov 04, 2009 1:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Zu LockMutex und den anderen habe ich leider nichts finden können.
Momentan bin ich am rumprobieren mit Semaphores... singlethreaded tun sie was sie sollen, aber das Bilderprogramm hab ich damit nicht stabil gekriegt :/
Manchmal kommt einfach "blitzcc.exe funktioniert nicht mehr", manchmal kommt ne MAV beim LoadImage ... manchmal zeigt auch einfach der Text-Befehl nichts mehr an. Woran es liegt, weiß ich nicht Sad
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Xaymar

ehemals "Cgamer"

BeitragDo, Nov 05, 2009 15:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok ich habe alle benötigten funktionen für ein einwandfreies Threading gefunden. Ich stelle nun eine decls zusammen Smile

Edite die decls und beispiele dann später hier rein

Edit: rauseditiert Wink Ich mache dafür ein extra Thread
Warbseite
  • Zuletzt bearbeitet von Xaymar am Do, Nov 05, 2009 20:49, insgesamt 3-mal bearbeitet

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic DLLs und Userlibs

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group