Seite 2 von 5

Verfasst: 25.01.2007 01:38
von ts-soft
AND51 hat geschrieben:SOmit muss ich ja jede Variable quasi zweimal anlegen?!
Nein, nur eine für das MutexObject. Mithilfe dieses Objects, lassen sich alle
Shared (Global) Vars schützen durch LockMutex.

Lokale Variablen sind dadurch geschützt das jeder Thread einen eigenen
Stack hat. Für Static Variablen möchte ich das aber nicht behaupten, die sind
IMHO ungeschützt.

Verfasst: 25.01.2007 09:31
von NicTheQuick
Der Threadsafe-Modus in den Compiler-Optionen ist nur wichtig für die
Stringbearbeitung. Dabei kann es sich aber auch um verschiedene Strings
handeln.
Das heißt wenn du in verschiedenen Threads gleichzeitig mit Strings
arbeitest, dann sorgt "Threadsafe" dafür, dass sich die Stringoperationen
nicht in die Quere kommen.

Verfasst: 25.01.2007 12:24
von Kaeru Gaman
und wie ist das jetzt mit globalen?

ich bin davon ausgegangen, dass gemeinsamer zugriff auf ne speicherstelle
sicher sein muss, schon seit einführung das ersten pentium.
wieso sollte da in PB irgendwas anders sein....

@ts

würde mich mal interessieren, wie und was du getestet hast.
soweit ich das verstanden habe,
geht es toshy um gemeinsamen zugriff auf eine global-steuerung von mehreren threads aus,
und das läuft bei mir problemlos.

Code: Alles auswählen

Global glob 

Procedure test1(a)
  For n=0 To 999999999
    glob+1
  Next
EndProcedure

Procedure test2(a)
  For n=0 To 99999999
    glob+1
  Next
EndProcedure

Procedure test3(a)
  For n=0 To 9999999
    glob+1
  Next
EndProcedure

NR1 = CreateThread(@test1(), 0)
NR2 = CreateThread(@test2(), 0)
NR3 = CreateThread(@test3(), 0)
For n=0 To 999
  glob+1
Next
WaitThread(NR1)
Debug glob
klar, die ausführung dauert ne weile, und die CPU wird a bissel wärmer,
aber aufhängen tut sich das ding nich.

Verfasst: 25.01.2007 12:45
von NicTheQuick
Der PureBasic-Compiler kann nur einen String gleichzeitig bearbeiten. Ich
versuche es in Stichworten zu erklären:

- Thread 1 bearbeitet einen String
- Windows wechselt zu Thread 2
- Thread 2 fängt an einen String zu bearbeiten
- die globalen Werte zur Stringbearbeitung in PB werden verändert
- Windows wechselt zu Thread 1
- Die Stringbearbeitung wird falsch abgeschlossen, weil Thread 2 gleichzeitig auf die Stringproceduren zugegriffen hat
- "PureBasic.exe hat einen Fehler verursacht..."

Hier mal ein Code, der nur mit Threadsafe funktioniert:

Code: Alles auswählen

Global s.s = "hallo", Quit.l = #False
Procedure Thread(dummy.l)
  Repeat
    If s = "hallo"
      s + " du da!"
    ElseIf Right(s, 7) = " du da!"
      s = Left(s, 5)
    EndIf
  Until Quit
EndProcedure

thread1 = CreateThread(@Thread(), 0)
thread2 = CreateThread(@Thread(), 0)

OpenConsole()

Repeat
  PrintN(s)
  Delay(100)
Until GetAsyncKeyState_(#VK_ESCAPE)

Quit = #True
WaitThread(thread1)
WaitThread(thread2)

CloseConsole()
Eigentlich sollte meinem Wissen zufolge der Fehler auch auftreten, wenn
zwei unterschiedliche Strings manipuliert werden, aber da ist nichts
passiert.
Um es selbst zu testen, einfach hinter "Procedure" noch ein "Protected s.s = "hallo""
einfügen.

Verfasst: 25.01.2007 13:18
von HeX0R
ReadMe hat geschrieben: For global stuff, the rule is that access to the numeric types is atomic, this
means if thread A does "a = 512" and thread B does "a = 123" at the exact
same time, one is actually fully completed before the other is executed.
(the reason is that threads never switch between the simple asm instructions
like mov, add, push, pop, ...)
So you will end up with either 512 or 123 (depending of what came last), but
there will never be any mixup or something.

Basically everything that gets more complex than this (and is done on global things)
should be protected by a mutex.

Verfasst: 25.01.2007 13:35
von Kaeru Gaman
nu siehste woll?

....hab ich doch glei gesagt.
Toshy hat geschrieben:...Also kann es auch sein das Variable flag.b gleichzeitig von zwei Threads hochgezählt wird, da mache ich mit
b + 1 bzw. b - 1
Da ich ja nur einen kurzen Befehl nutze, dürfte es doch keine Probleme geben, oder?
...
Kaeru Gaman hat geschrieben:yup, kannst du sicher sein.

Verfasst: 25.01.2007 13:58
von ts-soft

Code: Alles auswählen

Global glob.l

Dim Threads.l(99)

Procedure Thread(dummy.l)
  Repeat
    glob + 1
  ForEver
EndProcedure

For I = 0 To 99
  Threads(I) = CreateThread(@Thread(), 0)
Next

Delay(5000)

For I = 0 To 99
  KillThread(Threads(I))
Next

Debug glob
Bei mir hängt sich das meist auf, und es sind nur 100 Threads, wie ich
Toshy einschätze möchte er mehr erstellen <)

Verfasst: 25.01.2007 14:14
von Kaeru Gaman
ich glaube nicht, dass er sich wirklich aufhängt,
das problem liegt wohl eher daran, dass du dieselbe proc mehrfach threadest.

ich habs mal timer getestet.

zum starten von 10 threads braucht er fast 2 sekunden,
zum starten von 20 threads braucht er fast 15 sekunden,
zum starten von 21 threads braucht er fast 18 sekunden.
anscheinend steigt das exponentiell an,
also braucht er einfach sehr lange,
um deine 100 threads auf derselben proc zu starten.

Code: Alles auswählen

Global glob.l 

Dim Threads.l(99) 

#LastThread = 20

Procedure Thread(dummy.l) 
  Repeat 
    glob + 1 
  ForEver 
EndProcedure 

Debug "1"
time = ElapsedMilliseconds()
For I = 0 To #LastThread 
  Threads(I) = CreateThread(@Thread(), 0) 
Next 
time = ElapsedMilliseconds() - time
Debug time
Debug "2"
Delay(5000) 
Debug "3"
For I = 0 To #LastThread 
  KillThread(Threads(I)) 
Next 
Debug "4"
Debug glob
egal wie viele threads Toshy verwenden will,
er wird bestimmt nicht hunderte derselben einfachen endloszähler starten wollen.

Verfasst: 25.01.2007 14:19
von ts-soft
>> das problem liegt wohl eher daran, dass du dieselbe proc mehrfach threadest.
Sonst machts doch keinen Spaß :lol:

Verfasst: 25.01.2007 14:29
von Kaeru Gaman
habs mal mit 10 identischen procs getestet, macht keinen unterschied.

wieauchimmer, ich finde, wilde spekulazius bringen nix....

es wäre erstmal interessant zu wissen, was Toshy im grunde vorhat.
aber was auch immer das ist, ich bezweifle einfach mal,
dass es eine ähnlichkeit mit dieser extremen versuchsanordnung hat.