Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

CriticalSection() - Real Multithreading for AutoHotkey.dll


  • Please log in to reply
4 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Using CriticalSection, you can write and read variables in several threads at the same time.

- lpCriticalSection:=CriticalSection() ;create and Initialize a new CriticalSection and return pointer which can be used in Lock() and UnLock().

- Lock(lpCriticalSection) ;EnterCriticalSection - other threads will be waiting for your code to finish

- UnLock(lpCriticalSection) ;DeleteCriticalSection - now other threads can access the variable(s).

- CriticalSection(lpCriticalSection) ;deletes CriticalSection

- CriticalSection() ;deletes all CriticalSections


Example should explain everything else.

You will need AutoHotkey.dll and AhkDllThread as well as CreateScript

Here you will find more information: MSDN.

Example requires AutoHotkey_H from this package
SetBatchLines,-1 ;Max performance
Loop 2 ;Create 2 CriticalSections and return pointer to use with Lock() and UnLock()
	_C%A_Index%:=CriticalSection()
;Get pointer to Variables to use in Alias()
pX:=getVar(x),pY:=getVar(y)

ThreadScript=
(
  #Persistent
  Alias(x,%pX% + 0),Alias(y,%pY% + 0) ;create Alias variables x+y, so you can use same variables in exe and dll
  Loop 2
     SetTimer,Label`%A_Index`%,50 ;Label1 and Label2 will be launched rapidly
  Return
   Label1:
    Lock(%_C1%)
    x.="new"
    UnLock(%_C1%)
  Return

  Label2:
    Lock(%_C2%)
    y.="newtext"
    UnLock(%_C2%)
)
dll:=AhkDllThread("AutoHotkey.dll")
dll.ahktextdll(ThreadScript)
Loop
  {
    Loop 2
      Lock(_C%A_Index%)
	lengthX:=StrLen(x),lengthY:=StrLen(y)
    Loop 2
      UnLock(_C%A_Index%)
    ToolTip % lengthX "-" lengthY
  }
Esc::ExitApp
To run it with AutoHotkey_L you will need LowLevel:
SetBatchLines,-1 ;Max performance
[color=red]LowLevel_Init()[/color]
;Create CriticalSection and return pointer to use with Lock() and UnLock()
Loop 2
	_C%A_Index%:=CriticalSection()
;Get pointer to Variables to use in Alias()
pX:=[color=red]__getVar[/color](x),pY:=[color=red]__getVar[/color](y)

ThreadScript=
(
  #Persistent
  Alias(x,%pX% + 0),Alias(y,%pY% + 0) ;create Alias variables x+y, so you can use same variables in exe and dll
  Loop 2
     SetTimer,Label`%A_Index`%,50 ;Label1 and Label2 will be launched rapidly
  Return
   Label1:
    Lock(%_C1%)
    x.="new"
    UnLock(%_C1%)
  Return

  Label2:
    Lock(%_C2%)
    y.="newtext"
    UnLock(%_C2%)
)
dll:=AhkDllThread("AutoHotkey.dll")
dll.ahktextdll(ThreadScript)
Loop
  {
    Loop 2
      Lock(_C%A_Index%)
	lengthX:=StrLen(x),lengthY:=StrLen(y)
    Loop 2
      UnLock(_C%A_Index%)
    ToolTip % lengthX "-" lengthY
  }
Esc::ExitApp
CriticalSection.ahk Note :!: AutoHotkey_H and AHK.dll have a build in function Lock() + UnLock(), they are faster than user defined functions
Therefore if you are using AHK_H, delete the Lock and UnLock functions from CriticalSection.ahk.
[color=red]Lock(LPCRITICAL_SECTION){
  DllCall("EnterCriticalSection","UInt",LPCRITICAL_SECTION)
}
UnLock(LPCRITICAL_SECTION){
  DllCall("LeaveCriticalSection","UInt",LPCRITICAL_SECTION)
}[/color]
CriticalSection(LPCRITICAL_SECTION="ÿÿÿÿ"){
  static
  If (LPCRITICAL_SECTION!="" and LPCRITICAL_SECTION!="ÿÿÿÿ"){
    DllCall("DeleteCriticalSection","Uint",LPCRITICAL_SECTION)
    Return
  } else if (LPCRITICAL_SECTION=""){
    Loop % (count){
      DllCall("DeleteCriticalSection","Uint",&CriticalSection%count%)
      count:=0
    }
    Return
  }
  count++
  VarSetCapacity(CriticalSection%count%,24)
  DllCall("InitializeCriticalSection","Uint",&CriticalSection%count%)
  Return &CriticalSection%count%
}


Futurity
  • Members
  • 21 posts
  • Last active: Feb 08 2011 02:42 PM
  • Joined: 13 Feb 2007
Great job!

I will use it in my script.

One problem though, it does not work with AutoHotkey_N41:
<!-- m -->https://ahknet.autoh... ... CE_N41.zip<!-- m -->

When I put a msgbox after
Thread(ThreadScript "`nInclude:IncludeEnd"),
the script never reaches it.

It works fine, with:
<!-- m -->https://ahknet.autoh... ... ey_N10.zip<!-- m -->

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
I have changed examples to work with most current AHK.dll.

n-l-i-d
  • Guests
  • Last active:
  • Joined: --
Where are LockSec() and UnLockSec()?

I used AutoHotkey_H, copied the necessary code and included the files mentioned...

Error: Call to nonexistent function.

Specifically: LockSec(_C%A_Index%)


:?:

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Sorry it should be Lock() and UnLock(), I have updated examples.