| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen   | 
	
	
	
		| Autor | 
		Nachricht | 
	
	
		Eternal_pain
 
  
  Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
  | 
		
			
				 Verfasst am: 30.08.2012, 23: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, 09: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, 11: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, 11: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, 01: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: 4712 Wohnort: ~/
  | 
		
			
				 Verfasst am: 01.10.2012, 15: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 | 
		 | 
	
	
		  | 
	
	
		 |