Jump to content

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

real thread handling


  • Please log in to reply
28 replies to this topic
daniel2
  • Guests
  • Last active:
  • Joined: --
Interesting. I noticed that the thread ID's are always 8 apart. I'm thinking that the 4 limit must be related to how AHK internally handles its own threads & maybe your trying to tap into something that is reserved...
New internal ahk threads do get spawned using dll method..(like hotkey/context menu.. etc) but using Loop the threads still seem to use the thread-queue as described in help :?

Thanks for the response!

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I've no idea why it would be limited to 3 threads per script. However, AutoHotkey isn't designed to support multiple threads except in the case of the keyboard/mouse hook (which both share a second thread when they're active). Therefore, AutoHotkey isn't thread-safe, particularly when it comes to reading/writing variables. Therefore if the second thread does anything that interferes with something the main thread is doing (or vice versa), using multiple threads in a script might cause unexpected behavior or possibly even crashes.

It's also possible there could be other problems just from the mere existence of a second thread that is running parts of the script in parallel with the main thread. The program simply isn't designed to do that. An extensive code-review would be necessary if anyone wants to verify that it's safe.

AutoHotkey doesn't currently support multiple process-threads due to the need to make many sections thread-safe, which in turn would:
1) Increase code size.
2) Reduce performance in many areas due to the need to enforce thread-safety.
3) Be very costly in development time (probably 4-8 weeks of full-time work).

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Many thanks for the clarification Mr.Chris. :)

I guess my application exceptionally escapes the evil with a second parallel thread.
I will send you a copy of my code before I post it in S & F.

Thanks again :)

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
It looks like some worarounds for quirks are possible :) (although they might not work in the next version ;) ). For instance, Loop seems to work ok but specifying the number of times to Loop with the Loop command does not seem to work.
#Persistent

CoordMode, ToolTip, Screen 

CBA_FirstLoop := RegisterCallback( "FirstLoop" ) 

CBA_SecondLoop := RegisterCallback( "SecondLoop" ) 

DllCall( "CreateThread", UInt,0, UInt,0, UInt,CBA_FirstLoop, UInt,0, UInt,0, UInt,0 ) 

DllCall( "CreateThread", UInt,0, UInt,0, UInt,CBA_SecondLoop, UInt,0, UInt,0, UInt,0 ) 

return 



FirstLoop() { 

  X := 0 



  Loop  

  { 

     X += 1 

	 If (X > 40) {

	  Tooltip,,, 1

	  Exit

	}

	 MouseGetPos, OutX, OutY

     ToolTip, X = %X%,,(OutY - 10), 1 

	 Sleep, 200	 

  } 

  Return

} 



SecondLoop()  { 

  Y := 2 

  c := (Y)**40

  Loop

  { 

     Y *= 2 

	 If (Y > c) {

	  Tooltip,,, 2

	  Exit

	}

	 MouseGetPos, OutX, OutY

     ToolTip Y = %Y%,,(OutY + 10), 2 

	 Sleep, 150

  } 

  Return

}





corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Unfortunately, this trick does not work as well if you compile AutoHotkey using VC++ 2005 Express. It seems to break at the first If statement.
Edit: hmm, it seems to only run for a brief moment then break with most lines of code...

viciouskinid
  • Members
  • 136 posts
  • Last active: Jul 26 2008 01:34 AM
  • Joined: 23 Jun 2007
is their a way to sent a variable to the thread like the path of the script %A_ScriptDir%

engunneer
  • Moderators
  • 9162 posts
  • Last active: Sep 12 2014 10:36 PM
  • Joined: 30 Aug 2005
you could maybe use Majkinetors IPC module for interprocess communication. you may be able to communicate between the threads that way.

RaptoR
  • Members
  • 22 posts
  • Last active: May 04 2008 01:12 PM
  • Joined: 27 Jun 2007

Thread programming is known to be tricky and quite complex: after running tasks in parallels, people will ask ways to synchronize threads, to share data between threads, and so on. A real Pandora box! :-)


It is not necessary to be that complex :-) Take a look at Erlang, the language that was used by a lot of people who created software with very high level of concurrency (esp. telecom requires this). You might be surprised, but there is no synchronization, data sharing between threads and so on in Erlang. :-) Its concurrency model (called "actors") is quite simple but efficient.

Szeraax
  • Guests
  • Last active:
  • Joined: --
Sorry to rez a dead thread (haha, good pun I know) But i've found that the best way to go for me, using a sad technique, is to just have a temp file be my "inter process communication" My files can communicate commands, URLs, Return() data, or whatever else i need between the programs. Again, this is a sad, dirty way to do it, but it has worked for me.

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
ahkdll V6. 4/28/09
Multi-threading
After
Thread, priority, 9999
the next function will run in a separate thread.
requires a slowly looping ahk thread in the background
Examples:
testRecursive.ahk
testRecursiveHost.ahk
testThreads.ahk
testThreadsHost.ahk

Edit:

The above has been replaced with a simpler multi-threading model using multiple copies of the dll
see examples here
It turns out, I can just load the dll multiple times under different names.
giving thread local scripts. Shared thread variables should be easy with Lexikos' __alias(alias, alias_for) function in LowLevel..

Its probably best to keep separate copies of functions in scripts especially if you want to run time consuming functions at the same time: as in this example, however, sharing of functions is possible, if you avoid entangled variables (gui variables and builtin's such as A_Index and A_ScriptName), and don't run them at the same time.

  • Guests
  • Last active:
  • Joined: --

#Persistent

CoordMode, ToolTip, Screen 

CBA_FirstLoop := RegisterCallback( "FirstLoop" ) 

CBA_SecondLoop := RegisterCallback( "SecondLoop" ) 

DllCall( "CreateThread", UInt,0, UInt,0, UInt,CBA_FirstLoop, UInt,0, UInt,0, UInt,0 ) 

DllCall( "CreateThread", UInt,0, UInt,0, UInt,CBA_SecondLoop, UInt,0, UInt,0, UInt,0 ) 

return 



FirstLoop() { 

  X := 0 



  Loop  

  { 

     X += 1 

	 If (X > 40) {

	  Tooltip,,, 1

	  Exit

	}

	 MouseGetPos, OutX, OutY

     ToolTip, X = %X%,,(OutY - 10), 1 

	 Sleep, 200	 

  } 

  Return

} 



SecondLoop()  { 

  Y := 2 

  c := (Y)**40

  Loop

  { 

     Y *= 2 

	 If (Y > c) {

	  Tooltip,,, 2

	  Exit

	}

	 MouseGetPos, OutX, OutY

     ToolTip Y = %Y%,,(OutY + 10), 2 

	 Sleep, 150

  } 

  Return

}



Does this work with _L? Even it doesn't seem to work with Basic though. The tooltip doesn't get updated.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Read Chris' post. In particular,

The program simply isn't designed to do that.



fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
On a related request, how about being able to access threads below on the callstack and being able to abort them?
Lets say I have a somewhat heavyweight function that gets called every time the glabel of an edit control is triggered, and I want to run it with the latest values of the edit control from start to finish. It would be nice if one could simply stop the previous thread without having to put hardcoded checks in there at all places.

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
fragman++
In fact, in a semi-recent thread, the OP wanted to know how to stop all threads without reload. It turned out to be impossible without the use of AutoHotkey.dll ...

I believe infogulch suggested a syntax like
Exit, 3