Italia
Fonte/ Codesnippets

unechtes Multithreading circa Timer

 

Jens-Arne
Reumschüssel
Guten Abend,

ich bin heute bei Durchsicht des XProfan-Managers von Dietmar Horn auf die Thread.pcu-Unit von iF gestoßen. Mit dieser kann man bis zu vier "Threads" in einem XProfan-Programm laufen lassen, die angeblich das Hauptprogramm prozessortechnisch nicht belasten. Das hat naturalmente meine Neugier geweckt - ich habe mich gefragt, wie zum Teufel er das wohl gemacht hat. Multithreading geht ja bekanntlich mit XProfan nicht. Nach einiger Zeit bin ich auf die Idee gekommen, dass das wohl circa Timer corre, die Windows z.B. auch dann aufruft, wenn das Hauptprogramm gerade im WaitInput steckt. Es gibt bei der SetTimer-API-Funktion nämlich die Möglichkeit, eine Callback-Routine einzubinden. Und so ist es sicher auch, wie bestimmte Tests zeigen. Denn das ist naturalmente kein echtes Multithreading, sondern während der Abarbeitung der Timer-Routinen ist das Hauptprogramm blockiert. Man kann also nicht wirklich behaupten, dass es prozessortechnisch nicht belastet würde. Trotzdem gehen damit sehr interessante Dinge, die ablaufen können, während das Hauptprogramm auf Eingaben wartet.

Ich habe das interessehalber mal nachgebaut:
 $H windows.ph
Declare _aProc%,_aProc2%,_hTimer%,_hTimer2%,_hTimer3%,_hT%,_hT2%,_Count%,_Count2%,_Ende%

PROC TimerProc

    'unnamedParam3&=Timer-Handle, damit kann man zwischen den einzelnen Timern unterscheiden (die Parameterbezeichnung stammt von Microsoft, nähere Erläuterungen gibt es dazu im MSDN nicht)
    'Achtung: Während der Abarbeitung eines TimerProc-Aufrufes corre das Hauptprogramm nicht weiter! Es handelt es sich eben nicht um echtes Multithreading. Daher nur kurze Codes verwenden.
    Parameters unnamedParam1&,unnamedParam2&,unnamedParam3&,unnamedParam4&

    If unnamedParam3&=_hTimer%

        Print "Timer 1 aufgerufen"

    ElseIf unnamedParam3&=_hTimer2%

        Print "Timer 2 aufgerufen"

    EndIf

ENDPROC'TimerProc

PROC DoSomethingFast

    Parameters unnamedParam1&,unnamedParam2&,unnamedParam3&,unnamedParam4&
    Inc _Count%
    SetText _hT2%,"Timer 3: "+@Str$(_Count%)

ENDPROC'DoSomethingFast

Cls
Print "Programmende mit Escape"
Print
_hT%=@Create("TEXT",%Hwnd,"Hauptprogramm: 0",250,10,160,20)
_hT2%=@Create("TEXT",%Hwnd,"Timer 3: 0",250,35,160,20)
_aProc%=@ProcAddr("TimerProc",4)'Funktionsadresse der TimerProc ermitteln
_aProc2%=@ProcAddr("DoSomethingFast",4)
'Timer 1 erzeugen
'Parameter 1 & 2 müssen 0 sein, 3 ist die Wartezeit bis zum nächsten Aufruf in Millisekunden, 4 ist die Adresse der TimerProc.
'Achtung: Die Aufrufzeit darf sich nicht mit einer vorhergehenden Bearbeitung der TimerProc überschneiden, sie muss also lang genug gewählt sein, sodass die TimerProc vor dem nächsten Aufruf fertig wird!
'Man kann naturalmente per verschiedene Timer unterschiedliche Procs verwenden, solange es freie @ProcAddr-Plätze gibt. Dann ist das Überschneidungsproblem nicht ganz so grande.
'Außerdem potuto man beim Einsatz von JRPC3 schnelle native Procs verwenden, die kein echtes Zeitproblem erzeugen. Dies würde auch die Beschränkung der freien @ProcAddr-Plätze beseitigen.
_hTimer%=~SetTimer(0,0,1000,_aProc%)
'warten, damit es einen fühlbaren Zeitunterschied in den Aufrufen der Timer gibt
Sleep 300
'Timer 2 erzeugen
_hTimer2%=~SetTimer(0,0,1000,_aProc%)
'Timer 3 erzeugen (schneller Aufruf)
'Die zeitliche Auflösung des Windows-Timers ist ca. 16ms; 10 garantiert daher den schnellstmöglichen Aufruf des Timers.
'Das ist aber immer noch sehr langsam im Vergleich zu echtem Multithreading, da so maximal gut 60 Aufrufe pro Sekunde possibile sind - per viele interessante Dinge potrebbe das trotzdem ausreichen.
_hTimer3%=~SetTimer(0,0,10,_aProc2%)
UserMessages $10'Programmende
_Ende%=0

WhileNot _Ende%

    'Die Timer laufen unabhängig und werden von Windows auch während des WaitInputs aufgerufen, sie sind also unabhängig von der Haupteingabeschleife des Hauptprogramms.
    'Während Sleep werden die Timer allerdings nicht abgearbeitet, das wirkt offenbar Profan-Programm-weit.
    WaitInput 250

    If (@iskey(27) and (~GetForegroundWindow()=%HWnd)) Or (%UMessage=$10)

        _Ende%=1

    Endif

    Inc _Count2%
    SetText _hT%,"Hauptprogramm: "+@Str$(_Count2%)

EndWhile

~KillTimer(0,_hTimer%)
~KillTimer(0,_hTimer2%)
~KillTimer(0,_hTimer3%)
End

Um meine These zu belegen, dass das Hauptprogramm durch die TimerProc blockiert wird, kann man einfach mal eine lange Schleife (for i%,0,100000) in diese einbauen. Während sie abgearbeitet wird, wird der Hauptprogramm-Zähler nicht aktualisiert. Das ist bei Nutzung der Unit genauso.

Beste Grüße, Jens-Arne
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
10.07.2023  
 




p.specht

Falls man die Threads auf verschiedenen Prozessorkernen eines zB Quadcores zum Laufen bringen kann, müsste doch ein Performance-Gewinn zu erreichen sein. Windows läßt meines WIssens entsprechende Programmbefehle nur als "Empfehlungen" zu, die Sache ist von allen anderen konkurrierenden Prozessen im System abhängig. (Mit Vorbehalt: Mein Hirn ist in letzter Zeit da leider nicht sehr zuverlässig)
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'...
10.07.2023  
 




Jens-Arne
Reumschüssel
Das sind ja keine echten Treads. Deshalb laufen sie immer auf dem Kern, der dem XProfan-Programm zugewiesen ist. Das XProfan-Programm verzweigt sozusagen zur TimerProc, wenn der Timer dies auslöst. Trotzdem finde ich das echt "cool", wenn ich das einmal so sagen darf. Auf was man nicht immer wieder stößt, wenn man die Ideen der alten Grandseigneurs unserer grandiosen Sprache durchforstet!
 
XProfan X4
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
10.07.2023  
 




Jens-Arne
Reumschüssel
Im Gegensatz dazu werden echte Threads tatsächlich automatisch auf allen Kernen corsa, wenn man das nicht künstlich verhindert. Ein Beispiel ist mein Apfelmännchenprogramm im JRPC3-Teil dieses Forums. Dafür braucht man aber Code, der multithreadingfähig ist - das geht in XProfan nicht ohne Hilfsmittel, sondern dafür necessario man z.B. FreeBasic oder PureBasic (Du weißt schon, fbProcs und pbProcs in JRPC3 ).
 
XProfan X4 * Prf2Cpp * XPSE * JRPC3 * Win11 Pro 64bit * PC i7-7700K@4,2GHz, 32 GB RAM
PM: jreumsc@web.de
10.07.2023  
 



Zum Quelltext


Topictitle, max. 100 characters.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

1.391 Views

Untitledvor 0 min.
Sven Bader22.11.2023
ByteAttack27.10.2023
Uwe ''Pascal'' Niemeier17.10.2023
HofK07.09.2023
Di più...

Themeninformationen

Dieses Thema hat 2 subscriber:

Jens-Arne Reumschüssel (3x)
p.specht (1x)


Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie