
Man könnte jetzt natürlich meinen "Das ist kein Bug, das ganze ist einfach nicht Thread-Safe, musst du halt selbst absichern...".
Trifft aber hier IMHO nicht zu. Das ganze ist doch ein sehr schwer zu findender Fehler, und speziell Anfänger von diesem Verhalten sicher verwirrt sind, den sobald jemand fragt ob er in einem Thread nun etwas schützen muss ist so ziemlich die 1. Aussage "Solange alle Thread nur vom selben lesen dann nicht, gemeinsame Schreibzugriffe schon". Und das trifft hier einfach nicht zu. Außerdem könnte man die Thread-Sicherung viel performanter innerhalb der CopyStructure() Procedure einbauen anstatt sie zu ummanteln, da man ja nur die dynamischen Teile der Struktur schützen müsste, die statischen Einträge hingegen nicht.
Code: Alles auswählen
EnableExplicit
#NB_Elements = 100
#NB_Threads = 100
; Switch to Test:
#LockCopy = #False
Structure myStruct
Map MyMap.i()
EndStructure
Global myGlob.myStruct
Define i
For i = 1 To #NB_Elements
myGlob\MyMap(Str(i)) = i
Next
Global _TMMMutex = CreateMutex()
CompilerIf #LockCopy
Global _CopyMutex = CreateMutex()
CompilerEndIf
Macro ThreadModalMessageBox(_Title, _Text)
LockMutex(_TMMMutex)
MessageRequester(_Title, _Text)
UnlockMutex(_TMMMutex)
EndMacro
Procedure myStructCopy(Dummy)
Protected myLocal.myStruct
Protected i
CompilerIf #LockCopy
LockMutex(_CopyMutex)
CompilerEndIf
CopyStructure(@myGlob, @myLocal, myStruct)
CompilerIf #LockCopy
UnlockMutex(_CopyMutex)
CompilerEndIf
If MapSize(myLocal\MyMap()) <> #NB_Elements
ThreadModalMessageBox("Error", "Element count does not match: " + Str(MapSize(myLocal\MyMap())))
End
EndIf
For i = 1 To #NB_Elements
If Not FindMapElement(myLocal\MyMap(), Str(i))
ThreadModalMessageBox("Fehler", "Element count match, but Element is missing: " + Str(i))
End
EndIf
Next
EndProcedure
For i = 1 To #NB_Threads
CreateThread(@myStructCopy(), 0)
Next
Delay(5000)