WEvent - Windows-Events zur Thread-Synchronisierung

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

Shaman

Betreff: WEvent - Windows-Events zur Thread-Synchronisierung

BeitragMi, Jul 13, 2011 19:47
Antworten mit Zitat
Benutzer-Profile anzeigen
WEvent ist eine Klasse zur einfachen und schnellen Synchronisierung von Threads.

Es wird dabei auf die Events von Windows zurückgegriffen.

Ein Thread postet (aktiviert) ein Event (über seine ID) mit Post(...)
während ein anderer Thread auf dieses Event wartet (per Wait(...) )
Das besondere ist, dass während des wartens der Thread stillgelegt wird,
und keine Prozessorleistung beansprucht (wie bei Repeat Until Event1=1 , oder so).

Es wird ein externes C++ File benötigt.

B-Max Code "shaman.mod\wevent.mod\wevent.bmx":
(Wie alle Codes von mir ist es als mini-Modul kozipiert )

Code: [AUSKLAPPEN]

Strict

Rem
bbdoc: Interface zu WindowsEvents
about: Wird zur Synchronisation von Threads benutzt <br>
   Als erstes werden die Events mit Start erstellt, <br>
   dann können einzelne Events mit Post(...) aktiviert und mit Reset(...) deaktiviert werden. <br>
   Auf ein Event wird mit Wait gewartet. <br>
   Es können maximal 100 Events gesteuert werden,
   d.h. Die Position (ID) des Events muss zwischen 0 und 100 liegen.
End Rem
Module shaman.WEvent

Import BRL.BASIC
Import "WEvent.cpp"

Extern
   Function _WEvent_Create:Int(pos:Int,state:Int)
   Function _WEvent_SetEvent:Int(pos:Int)
   Function _WEvent_ResetEvent:Int(pos:Int)
   Function _WEvent_WaitSingle:Int(pos:Int,time:Int)
   
End Extern

Rem
bbdoc: Globales System für WEvents
about: Muss mit Start(...) initialisiert werden
EndRem
Type WEvent
   Const WAIT_FAIL:Int=-1
   Const WAIT_TIME:Int=0
   Const WAIT_SUCCESS:Int=1
   
   Rem
   bbdoc: Initialisiert die Events
   returns: 1, wenn alle Events erfolgreich erstellt wurden
   about: <b> MUSS GANZ AM ANFANG AUFGERUFEN WERDEN </b> <br>
      Ohne diese Funktion schlagen alle folgene Funktionen fehl. <br><br>
      autoResetPosition: Ab der mit dieser Variable beschriebenen ID sind alle Events auto-reset, <br>
      d.h. nachdem ein Event geposted wurde und erfolgreich auf es gewartet wurde wird es automatisch resettet.
   End Rem
   Function Start:Int(autoResetPosition:Int=101)
      Local i:Int
      Local ret:Int
      For i=0 Until 100
         ret=ret&_WEvent_Create(i,(i<autoResetPosition))
      Next
      Return ret
   End Function
   
   
   Rem
   bbdoc: Aktiviert ein Event
   about:<b> pos: </b> Die ID des Events (zwischen 0 und 99)
      <br>Alle Threads, die mit Wait auf dieses Event warten, laufen weiter. <br>
      Das Event bleibt solange aktiviert, bis Reset aufgerufen wird.
   End Rem
   Function Post:Int(pos:Int)
      If pos>=100 Then Return -1
      Return _WEvent_SetEvent(pos)
   End Function
   
   Rem
   bbdoc: Resetet ein Event
   End Rem
   Function Reset:Int(pos:Int)
      If pos>=100 Then Return -1
      Return _WEvent_ResetEvent(pos)
   End Function
   
   Rem
   bbdoc: Wartet auf ein Event
   returns: WEvent.WAIT_FAIL , wenn ein Fehler stattfand <br>
      WEvent.WAIT_TIME, wenn nach Ablauf der Zeit das passende Event nicht aktiv ist
      WEvent.WAIT_SUCCESS, wenn erfolgreich gewartet wurde
   about: <b> pos: </b> Die ID des Events (zwischen 0 und 99)
      <br> <b>time: </b> Die Zeit in Millisekunden, die maximal gewartet wird   
   
   End Rem
   Function Wait:Int(pos:Int,time:Int)
      If pos>=100 Then Return -1
      If time<0 Then Return -2
      Return _WEvent_WaitSingle(pos,time)
   End Function
End Type




Die benötigte C++ Datei (WEvent.cpp):
Code: [AUSKLAPPEN]

/*
 * File:   Event.cpp
 * Author: Shaman
 *
 * Created on 23. Mai 2011, 18:08
 */

#include <cstdlib>
#include <windows.h>
#include <winbase.h>


using namespace std;

int test[100];
HANDLE hndlEvents[100];
HANDLE hndl;
int count;


extern "C"{

   int _WEvent_Create(int pos,int state)
   {
      hndlEvents[pos]=CreateEvent(NULL,(bool)state,false,NULL);
      if (hndlEvents[pos]==NULL) {return 0;}
      return 1;
   }
   
   int _WEvent_SetEvent(int pos)
   {
      return (int)SetEvent(hndlEvents[pos]);
   }
   
   int _WEvent_ResetEvent(int pos)
   {
      return (int)ResetEvent(hndlEvents[pos]);
   }
   
   int _WEvent_WaitSingle(int pos,int time)
   {
      DWORD ret=WaitForSingleObject(hndlEvents[pos],(DWORD)time);
      if (ret==WAIT_OBJECT_0) {return 1;}
      if (ret==WAIT_TIMEOUT) {return 0;}
      if (ret==WAIT_FAILED) {return -1;}
   }

}


ein Beispiel zeigt die Benutzung:
Code: [AUSKLAPPEN]

Strict

Import Shaman.WEvent

Print "Start="+WEvent.Start()

Global thread:TThread=CreateThread(Test,"5")
Delay 5
Global thread2:TThread=CreateThread(Test2,"5")

Delay 1000

Print "Event senden"
Print "Send="+WEvent.Post(5)

Global time1:Int=MilliSecs()
 
Print "Thread="+String(WaitThread(thread))
Print "Thread2="+String(WaitThread(thread2))

Print "Time="+String(MilliSecs()-time1)

End

Function Test:Object(data:Object)
   Local pos:Int=Int(String(data))
   Print "Position="+pos
   Return String(WEvent.Wait(pos,5000))
End Function

Function Test2:Object(data:Object)
   Local pos:Int=Int(String(data))
   Print "Position="+pos
   Return String(WEvent.Wait(pos,5000))
End Function

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group