Hallo Jimmy,
na klar! Jeder der beiden Hersteller verwendet unterschiedliche Optimierungsvarianten - insofern nicht unbedingt verwunderlich.
Viele Grüße,
Martin
PUBLIC Variabeln, DBF und Thread´s syncronisieren ?
Moderator: Moderatoren
- Martin Altmann
- Foren-Administrator
- Beiträge: 16513
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
hi,
das ganze bezieht sich auf eine Anfrage befreffen des Xbase++ Help Text
und der Sample zum Thema SYNC
hier nun die Zusammenfassung in meinem Code
so mit diesem Code wird 100% das richtige Ergebniss erzielt d.h. die
Threads müssen richtig SYNCronisiert sein sodas sie nicht auf die
Variablen gleichzeitig zugreifen können. Somit könnte man also Variablen
,die wie PUBLIC für alle Thread gelten sollen, gegen gleichzeitigen Zugriff
z.b. beim "schreiben" wie RLOCK() bei einer DBF zum "sperren" benutzen.
Mal sehen wie das ganze dann funktioniert wenn ich das Demo in die
activeX Application einbaue und damit meine Threads SYNCronisiere.
vielen danke allen für die Hilfe, besonders Günter
gruss by OHR
Jimmy
das ganze bezieht sich auf eine Anfrage befreffen des Xbase++ Help Text
und der Sample zum Thema SYNC
eine weitere Antwort aus dem Alaska ForumAlaska Support hat geschrieben: > wären dann die SYNC METHOD put, get davon betroffen d.h.
> während put ausgeführt wird kann nicht get ausgeführt werden ?
Stimmt. ut() und :get() sind als synchronized deklariert. Das heisst,
dass die IVAR :nCount immer auch die Länge des Arrays :aQueue
reflektiert.
Aber vorsicht, das Beispiel hat auch eine Unschärfe, es wird in der
Funktion Test() zuerst oQ:nCount abgefragt und dann oQ:get() gerufen.
In der Zeit zwischen des IVar Zugriffs und des Methodenaufrufs kann
sich die Anzahl der Elemente natürlich verhändert haben weil ein
anderer Thread ut() gerufen hat.
ok nachdem ich das nun begriffen hatte zusammen mit seinem BeipielRodd Graham hat geschrieben: Thread A - SyncVars():VarGet( 1 ) //suppose returns 10
-- context switch --
Thread B - SyncVars():VarGet( 1 ) // also returns 10
Thread B - SyncVars():VarPut( 1, 10 + 1 ) // writes 11
-- context switch --
Thread A - SyncVars():VarPut( 1, 10 + 1 ) // also writes 11
- you have lost one count
Threads are only blocked from the SYNC methods when another thread
has an active call to a SYNC method.
Put another way, the SyncVars():VarPut( cVar, SyncVars():VarGet( Var )
+ 1 ) is not executed atomically. The calls to :VarPut() and :VarGet()
are independent of one another. You just happened to code them into a
single expression. Expressions are not atomic, thread context switches
may occur in the middle of the expression evaluation
hier nun die Zusammenfassung in meinem Code
Code: Alles auswählen
PROCEDURE Main
LOCAL i, aT[4], j
LOCAL TimeOn := SECONDS()
LOCAL TimeDiff
CLS
FOR i:=1 TO 4
aT[i] := Thread():new() // Threads erzeugen
aT[i]:start( "Lucky4" ) // und starten
NEXT
ThreadWaitAll( aT )
? TimeDiff := SECONDS()-TimeOn
// Den Endstand anzeigen
FOR j:=1 TO 4
? SyncVars():VarGet( "Var"+LTRIM(STR(j)) )
NEXT
WAIT
RETURN // Threads beendet sind
** Code läuft in 4 Threads gleichzeitig ab
PROCEDURE Lucky4()
LOCAL i, nRow, nCol, j
LOCAL x,cString
LOCAL cThread := "T"+ltrim(str(ThreadId()))
LOCAL cVar
nRow := 15
nCol := (ThreadID()-2) * 10
DispOutAt( nRow, nCol, padl( cThread, 10 ) )
FOR i:=1 TO 1000
FOR j := 1 TO 4
cVar := "Var" + ltrim(str(j))
// Anzeige var Name ...
* DispOutAt( nRow+j, 0, cVar )
//
// eine dritte SYNC Methode
//
SyncVars():VarLock( nRow+j, nCol, cVar )
NEXT
NEXT
RETURN
*************************************************************
*
*
*
*************************************************************
CLASS SyncVars
PROTECTED:
CLASS VAR var1
CLASS VAR var2
CLASS VAR var3
CLASS VAR var4
EXPORTED:
// muss nun nicht mehr SYNC sein
INLINE CLASS METHOD VarPut( cVarName, value )
::&cVarName := value
return ::&cVarName
// muss nun nicht mehr SYNC sein
INLINE CLASS METHOD VarGet( cVarName )
return ::&cVarName
INLINE METHOD Init
MsgBox("SyncVar():New() ist verboten!")
RETURN self
INLINE SYNC CLASS METHOD InitClass
::var1 := 0
::var2 := 0
::var3 := 0
::var4 := 0
RETURN self
//
// all Code will be execute before other Threads can access it
//
INLINE SYNC CLASS METHOD VarLock( nRow, nCol, cVar )
LOCAL nVar := 0
// step by step
//
nVar := SyncVars():VarGet( cVar ) + 1
//
// just to show
//
SyncVars():VarPut( cVar,nVar)
//
// whole code will be execute by one Thread only
//
DispOutAt( nRow, nCol, nVar)
RETURN self
ENDCLASS
Threads müssen richtig SYNCronisiert sein sodas sie nicht auf die
Variablen gleichzeitig zugreifen können. Somit könnte man also Variablen
,die wie PUBLIC für alle Thread gelten sollen, gegen gleichzeitigen Zugriff
z.b. beim "schreiben" wie RLOCK() bei einer DBF zum "sperren" benutzen.
Mal sehen wie das ganze dann funktioniert wenn ich das Demo in die
activeX Application einbaue und damit meine Threads SYNCronisiere.
vielen danke allen für die Hilfe, besonders Günter
gruss by OHR
Jimmy