Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 31.08.2012, 00:51 Titel: Threadcall |
|
|
Hatte aus dem englischen Forum ein Beispiel dazu entdeckt und mal testweise damit experimentiert...
So ein 'kleiner' test funktioniert ganz gut, was aber bei Multithreading nicht zwingend viel heissen soll...
Ist mit dem neuen Threadcall einfaches handling mit Threads tatsächlich so möglich ohne komplexe Mutex's zu nutzen und ohne das früher oder später alles abstürzt weil (nahezu) gleichzeitig auf ein udt gelesen/geschrieben wird?
mein test/beispielcode:
Code: |
Type testudt
test1 as integer
test2 as integer
End Type
Sub testthread(byref tdata as testudt ptr, byref thread_stop as integer)
Dim td as Integer
do
'read tdata
?"Thread: ";tdata -> test1
?"Thread: ";tdata -> test2
'write tdata
tdata -> test1 = rnd*1000
tdata -> test2 = rnd*1000
sleep 100
loop until thread_stop
End Sub
Dim t as any ptr
Dim ts as integer
Dim tdata as testudt ptr = NEW testudt
screenres 200,200,32
t = threadcall testthread(tdata, ts)
do
'read tdata
?"Main: ";tdata -> test1
?"Main: ";tdata -> test2
'write tdata
tdata -> test1 = rnd*1000
tdata -> test2 = rnd*1000
sleep 100
loop until multikey(&h01)
ts = 1
threadwait (t)
|
_________________
 |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 31.08.2012, 10:20 Titel: |
|
|
Globale Variaben unterliegen immer, egal wie, dem MEA fehler, wenn sie mit mehreren Threads verwendet werden.
Nimm einfach mal das print aus dem thread raus, und ersetzt das sleep durch:
Code: |
Sub testthread(byref tdata as testudt ptr, byref thread_stop as integer)
Dim td as Integer
Dim ttot as double
do
'read tdata
td = tdata -> test1
'write tdata
tdata -> test1 = 1
if ttot < timer() then
sleep 1, 1
ttot = timer() + 0.1
end if
loop until thread_stop
End Sub
|
das erhöht massiv den zugriff auf die variable sowohl beim schreiben als auch beim lesen.
kannst auch das schreiben raus nehmen oder nur das schreiben drin lassen und das lesen raus nehmen. dann siehst du, das es nicht lange gut geht.
die Änderung sollte natürlich für beide code-abschnitte ausgeführt werden.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 31.08.2012, 12:11 Titel: |
|
|
Ein Blick in die Referenz lohnt, da sieht man, dass ThreadCall genauso ein Mutex braucht. Durch den einfacheren Aufruf kann man jetzt allerdings viel einfacher ein Dim Shared der Mutexvariable verhindern. |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 31.08.2012, 12:19 Titel: |
|
|
Ganz vergessen zu erwähnen: das "ts = 1" bzw. "thread_stop" ist auch eine Globale variable wenn du sie einem thread übergibst. Sprich, wenn du mehrere Threads hast, die auf diese Variable das "exit" prüfen, musst du diese ebenfalls mutexen.
quasi stat:
Code: |
'...
loop until thread_stop
|
ein
Code: |
'...
mutexlock(...)
If thread_stop = 1 then mutexunlock(...): exit do
mutexunlock(...)
loop
|
oder
Code: |
'...
mutexlock(...)
If thread_stop = 1 then exit do
mutexunlock(...)
loop
mutexunlock(...)
|
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 01.10.2012, 02:14 Titel: |
|
|
Ich benutze TSNE3.5
Folgendes Beispiel:
Code: |
Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
Dim As String MessageFromClient,ClientIpp
Dim As Uinteger ClientId
MessageFromClient=v_data
ClientId=V_TSNEID
ClientIpp= V_CallBackPtr->V_IPA
If V_CallBackPtr = 0 Then TSNE_Disconnect(V_TSNEID): Exit Sub
With *V_CallBackPtr
.V_Data += V_Data
check_Client_Nachricht(ClientId,MessageFromClient,ClientIpp)
.V_Data = ""
End With
End Sub
|
In der sub check_Client_Nachricht wird die Nachricht des Clients verarbeitet.
Dabei verwende ich sehr viele globale Variablen (Dim Shared).
Dies läßt sich leider auch nicht ändern.
Wie erreiche ich es, dass während die sub check_Client_Nachricht die Nachricht verarbeitet , der Thread aus oder gestoppt oder gesperrt ist?
Da ich nicht weiss, um welchen mutex es sich handelt, kann ich nicht einfach
mutexlock(keineAhnungWasDaReinkommt)
check_Client_Nachricht
mutexunlock(keineAhnungWasDaReinkommt)
schreiben.
Erschwerend kommt hinzu, dass in der sub check_Client_Nachricht manchmal auch Dateien geöffnet und geschlossen werden.
Was muss ich also tun, um die sub check_Client_Nachricht Threadlos zu bekommen? |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 01.10.2012, 16:49 Titel: |
|
|
Den Mutex musst du sowieso selbst anlegen und verwalten. TSNE_NewData würde also dann während der Verarbeitung deinen (selbstgewählten) Mutex sperren; wenn währenddessen eine neue Nachricht ankommt, stößt die Verarbeitung auf eben diesen Mutex und muss warten, bis die erste Nachricht ihn wieder freigegeben hat.
Zitat: | Was muss ich also tun, um die sub check_Client_Nachricht Threadlos zu bekommen? |
Lässt sich (von mir) nicht so leicht allgemein beantworten - du musst halt dafür sorgen, dass die gesperrten Phasen möglichst kurz sind. Z. B.
Code: | DIM AS Datentyp lokaleVariable
MUTEXLOCK meinMutex
lokaleVariable = zuSchuetzendeGlobaleVariable
MUTEXUNLOCK meinMutex
' ... weiterarbeiten mit der lokalen Variablen |
wobei sich dann natürlich während der weiteren Bearbeitung die zuSchuetzendeGlobaleVariable ändern kann. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
|