Future

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Thunder

Betreff: Future

BeitragSa, Dez 05, 2015 13:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo alle miteinander!
Sind zwar nicht mehr viele da, aber ich hab wieder was kleines für BlitzMax geschrieben.

Ich habe (so gut es ging) C++ Futures für BlitzMax implementiert.
Eine Future ist ein Objekt, das eine Aufgabe/Funktion asynchron ausführt und das man dann nach dem Rückgabewert abfragen kann, wenn man ihn braucht. In C++ sieht das so aus
Code: [AUSKLAPPEN]
auto str = "irgendein langer string der verschluesselt werden soll"s;
auto fut = std::async( AES(str) );
// tue irgendwas anderes
auto encrypted = fut.get();


In der zweiten Zeile wird die Funktion AES(x) asynchron aufgerufen (was ein future objekt erzeugt, das wir in fut speichern).
D.h. während die Funktion läuft, läuft der Code einfach weiter. Wenn man fut.get() aufruft und die Funktion noch nicht zu Ende ist, wird gewartet bis sie zu Ende ist und der return wert geliefert. Wenn sie zu dem Zeitpunkt schon beendet ist, wird der Return wert sofort geliefert.

In BlitzMax schaut das ganze leider etwas klobiger aus Very Happy Das gleiche Beispiel sähe mit meinem Modul so aus
BlitzMax: [AUSKLAPPEN]
Local str:String = "irgendein langer string der verschluesselt werden soll"
Local fut:Future = Future.Create(AESWr, str)
' tue irgendwas anderes
Local encrypted:String = String( Future.get() )

Function AESWr:Object(o:Object)
Return Object(AES(String(o)))
EndFunction


Da ich in BlitzMax mit Object arbeiten musste, gibt es zwei Unannehmlichkeiten:
1. Alle Funktionen, die nicht aussehen wie f:Object(o:Object) brauchen Wrapper
2. Das Übergeben von primitiven Datentypen als Parametern und zurückgeben von primitiven Datentypen ist wegen Object nicht möglich. Dazu braucht man Wrapper-Types.

Trotzdem mag ich die Idee, weil man sich nicht um Threading und Locking kümmern muss.
Das Modul ist übrigens so implementiert, dass es sich auch im nicht-multithreaded modus kompilieren lässt (dann wird halt auch nichts gleichzeitig ausgeführt).

Modul-Download + Beispiele: https://www.blitzforum.de/upload/file.php?id=13090

1. Beispiel:
BlitzMax: [AUSKLAPPEN]
Local s1:String, s2:String, time = MilliSecs()

Local webpages:Future[] = [ Future.Create(LoadHTTPHeaderWr, "www.cplusplus.com"), ..
Future.Create(LoadHTTPHeaderWr, "www.gmx.net"), ..
Future.Create(LoadHTTPHeaderWr, "www.blitzforum.de"), ..
Future.Create(LoadHTTPHeaderWr, "www.heise.de"), ..
Future.Create(LoadHTTPHeaderWr, "derstandard.at"), ..
Future.Create(LoadHTTPHeaderWr, "de.wikipedia.org")]


For Local fut:Future = EachIn webpages
Print "header of "+String(fut.getParameter())
Print String(fut.get())
Next

time = MilliSecs() - time

Print "time = "+time+" ms"

Function LoadHTTPHeaderWr:Object(o:Object)
Return Object(loadhttpheader(String(o)))
EndFunction

Function LoadHTTPHeader:String(host:String)
Const path:String = "/"

Local sock:TSocket = TSocket.CreateTCP()
If Not sock.connect(HostIp(host), 80) Then Return Null
If Not sock.connected() Then Return Null

Local stream:TSocketStream = TSocketStream.Create(sock)
If stream = Null Then Return Null
Local r:String

Try
stream.WriteLine "GET "+path+" HTTP/1.1"
stream.WriteLine "Host: "+host
stream.WriteLine "Connection: close"
stream.WriteLine ""

While Not Eof(stream)
Local s$ = ReadLine(stream)
If s = "" Then Exit
r:+s+"~n"
Wend

Catch e:Object
stream.close
Throw e
EndTry

stream.close

Return r
EndFunction


Läuft bei mir:
threaded: in ~1000 ms
nicht threaded: in ~ 1200 ms

Das 3. Beispiel zeigt die Callback-Futures, wo ich mir nicht sicher bin, ob die schon funktionieren...
eine CallbackFuture nimmt in Create noch einen dritten Parameter, nämlich ein Callback, das aufgerufen wird, wenn der Returnwert bereitsteht.

BlitzMax: [AUSKLAPPEN]
Local str:String = "irgendein langer string der verschluesselt werden soll"
Local fut:Future = CBFuture.Create(AESWr, str, finished)
' tue irgendwas anderes
Local encrypted:String = String( Future.get() )

' this function is called, when return value of future is valid
Function finished(fut:Future)
Print "finished encrypting '"+fut.getParameter()+"'"
EndFunction

Function AESWr:Object(o:Object)
Return Object(AES(String(o)))
EndFunction


Problem : ich habe das gefühl, dass Print/WriteStderr etc. nicht thread-safe sind.. :/

Alle Funktionen:
BlitzMax: [AUSKLAPPEN]
Type Future
' erstellt eine neue Future
' Parameter cb wird ignoriert
Function Create:Future(func:Object(blub:Object), o:Object, cb(f:Future) = Null)

' gibt den Wert o zurück, der bei Create übergeben wurde
Method getParameter:Object()

' gibt True zurück, wenn der Return Wert schon bereit steht
Method valid()

' gibt True zurück, falls es Probleme mit der ausführung gab
Method bad()

' wartet, bis die Ausführung der Funktion der Future beendet ist
Method wait()

' gibt den Return wert der Future zurück
' Falls er noch nicht bereit steht, wird gewartet
Method get:Object()
EndType

Type CBFuture Extends Future
' wie Future.Create
' cb ist der Callback der aufgerufen wird, wenn der Return wert bereit steht
Function Create:CBFuture(f:Object(blub:Object), o:Object, cb(f:Future))
EndType
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit
  • Zuletzt bearbeitet von Thunder am Mo, Dez 07, 2015 21:29, insgesamt einmal bearbeitet

DAK

BeitragMo, Dez 07, 2015 16:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Das schaut recht cool aus! Find ich eine nette Idee, so auf die Art Instant-Multithreading.
Gewinner der 6. und der 68. BlitzCodeCompo

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group