Threads und Mutex bei LinkLists - Fragen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Threads und Mutex bei LinkLists - Fragen

Beitrag von Bisonte »

Da bin ich wieder um mit Fragen zu nerven ;)

Code: Alles auswählen


; Beispielcode ohne Zweck...

Procedure ConnectClient(*ClientID)     
  
  Shared Mutex
    
  ; Part I : hier steht viel Code ....
    
  LockMutex(Mutex)    ; entfernen Sie das ';' um den Unterschied zu sehen
    
  ;Hier die LinkList
  AddElement(Client())
    Client()\ID = ClientID
    Client()\Accountname = Account.s
      
  UnlockMutex(Mutex) ; entfernen Sie das ';' um den Unterschied zu sehen
        
  ;Part II : Hier steht noch mehr Code
    
EndProcedure
  
  Mutex = CreateMutex()
  
  Empfang(ThreadNumber) = CreateThread(@ConnectClient(), ClientID)

Wenn jetzt, sagen wir mal 30 Clients gleichzeitig versuchen sich einzuloggen,
hält die Abbarbeitung eines Threads, wenn er bei LockMutex ankommt an, wenn
ein anderer Thread dort gerade Daten in die Liste einfügt ? Oder muss man
das anders realisieren, damit die Werte in der Liste nicht durcheinanderkommen ?

Und Wenn ich jetzt z.B. in Part II noch eine Stringoperation habe, die NUR in
diesem Thread aktiv ist, also z.B. String.s = "hallo", muss ich dann auch
wieder LockMutex anwenden (Also immer bei Manipulationen bei String und Double) ?

Wenn ich aus einem Thread eine andere Procedure aufrufe, die Strings verändert,
muss ich den Procedureaufruf auch in Mutex einbinden (also mehrfache Aufrufe von LockMutex()) ?

Kann man in einem Thread auch einen weiteren Thread aufrufen und dann mit Waitthread
auf den aufgerufenen warten ohne das man mit merkwürdigem Verhalten rechnen muss ?

Muss man bei Änderung von Globalen Variablen auch "Mutexen" ?
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
gnasen
Beiträge: 578
Registriert: 01.08.2007 14:28
Computerausstattung: PB 4.60

Beitrag von gnasen »

Es gibt 2 Möglichkeiten die Mutex zu "locken"

1. LockMutex() wartet darauf, bis die Mutex freigegeben ist und greift dann drauf zu.
2. TryLockMutex() guckt ob die Mutex freigegeben ist. Wenn ja, lockt er sie, wenn nicht lässt er es.

Damit sollte das kein Problem sein.

Ich schicke dir mal ne PM wie ich das ganze mit allem drum und dran gelöst habe, wäre nen bisl viel hier rein zu posten
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Das klingt gut.

Mit der ganzen Thread Geschichte wollte ich mich ja an ein Serverprogramm ranwagen.

Wobei ich mich bei einem Server immer noch Frage, welche Teile man
am besten in einen extra laufenden Thread packen sollte.

Ich habe schonmal SendNetworkData und ReceiveNetworkData in jeweilige Proceduren getan.
Und eine Procedure die die ganze Servereventloop beinhaltet, also
von Repeat über ServerEventabfrage bis Until...

Allerdings um die Kommunikation sicherzustellen, d.h. damit auch nur ein Befehl
vom Client an den Server kommt, hab ich folgendes gemacht :

Code: Alles auswählen

Procedure     Send_Data(Verbindung.l, String.s)

Protected Laenge.l

If Verbindung

  Laenge = Len( String.s)

  SendNetworkData( Verbindung, @Laenge, 4)

  Delay(10)

  SendNetworkString( Verbindung, String.s)

  Delay(10)

EndIf

EndProcedure
Procedure.s   Receive_Data(Verbindung.l)

Protected *Buffer1.l, *Buffer2.l, Laenge.l, String.s

If Verbindung

  *Buffer1 = AllocateMemory(4)

  ReceiveNetworkData( Verbindung, *buffer1, 4)

  Laenge = PeekL( *Buffer1)

  FreeMemory( *Buffer1)

  Delay(5)

  *Buffer2 = AllocateMemory(Laenge)

  ReceiveNetworkData( Verbindung, *Buffer2, Laenge)

  String.s = PeekS( *Buffer2, Laenge)

  FreeMemory( *Buffer2)

  Delay(5)
    
  ProcedureReturn String.s

EndIf

EndProcedure
Es sind ja nun 2 Sende und 2 Empfangsteile in jeder Procedure....
kann man das so machen, ohne das Probleme beim Senden und Empfangen entstehen ?

Und zu guter letzt, Welche Teile vom Server sollten in einen Thread getan werden.... Ich steh irgendwie dabei mit nem Brett vorm Kopp aufm Feld....
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Der Server bekommt seine Events ohnehin sequentiell, von daher ist dort ein Mutex eigentlich unnötig.

Was du auf Threads auslagerst hängt vom Aufgabengebiet des Servers ab.
Soll er z.B. als Art Proxy dienen, der sich auch zu anderen Clients weiterverbinden soll, so sollten diese Verbindungsversuche in Threads ausgelagert werden.
Weil solche Verbindungsversuche zu z.B. toten Clients u.U. einige Sekunden dauern können und dann alles zum erlahmen bringen würden.

Als stinknormale Vermittlungsstelle zwischen Clients machen verschiedene Threads nicht wirklich Sinn, höchstens den kompletten Server könntest du in einen Thread packen.
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Mit Hilfe von gnasen hab ich jetzt den ganzen Server in einem Thread, und
es funktioniert so ganz gut...

Es ist wirklich ein interessantes Konzept, das er mir da gezeigt hat... :allright:

Der Server soll so eine Art AntiCheat-Server werden, der eigentlich nur Pings verarbeitet und bei einem Ping der einen Cheatcode mitsendet ein
Logoff an den Client sendet und den Spieler sperrt. So als Art "Punkbuster" oder "FLCD" für andere Spiele die ihre Userverwaltung per Datenbank steuern.
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Antworten