Built-in function to enwrap an object for multi-thread use. Such objects can be used from multiple threads without causing a crash.
OutputVar := CriticalObject(Object, lpCriticalSection)Function Example: obj := CriticalObject(MyCriticalObject)
The name of the variable in which to store the created object.
Existing Object or CriticalObject to use, this can be also a pointer.
When CriticalObject is given, its CriticalSection
will be used and second parameter will be ignored.
When this parameter is empty new object will be created and used.
Pointer to a CriticalSection to use. When this parameter is omitted new CriticalSection will be created unless CriticalObject was given in first parameter, then its CriticalSection will be used.
How does it work:
To retrieve the pointer to original object from CriticalObject use:
object := CriticalObject(CriticalObject,1)
To retrieve the pointer to CriticalSection use:
lpCriticalSection := CriticalObject(CriticalObject,2)
When last reference to internal object is deleted, CrticalSection is deleted as well.
Operations like obj.key++ obj.key--, obj.key += 1, obj.key /= 2 and others access the object 2 times, once to get the value and another time to set the value.
Those operations will not produce desired result in multi-threaded environment when 2 or more threads change the value of an item.
To work around that we will need to lock/unlock the CriticalSection manually:
obj:=CriticalObject({a:0}) ; Create new CriticalObject script:=" ( obj:=CriticalObject(a_args[1]) ; get CriticalObject from pointer lpCS:=CriticalObject(obj,2) ; get CriticalSection loop 1000000 EnterCriticalSection(lpCS),obj.a++,LeaveCriticalSection(lpCS) ; manually lock and unlock CriticalSection )" threads:=[] loop 4 threads.Push(TlsThread(script,ObjPtr(obj) "")) ; create 4 threads passing the pointer (as string!) to command line parameters While threads[1].AhkReady() || threads[2].AhkReady() || threads[3].AhkReady() || threads[4].AhkReady() ; wait for threads to finish ToolTip obj.a MsgBox obj.a ; = 4000000
obj := CriticalObject() ; Create new critical object Threads:=[] Loop 4 ; Create 4 Threads. threads.Push(NewThread("obj:=CriticalObject(" ObjPtr(obj) ")`nLoop`nobj[" A_Index "]:= A_Index")) Loop ; Show current content of object. ToolTip obj.1 "`n" obj.2 "`n" obj.3 "`n" obj.4 Esc::ExitApp