Threads

The current thread is defined as the flow of execution invoked by the most recent event; examples include hotkeys, SetTimer subroutines, custom menu items, and GUI events. The current thread can be executing functions within its own subroutine or within other subroutines called by that subroutine.

Although AutoHotkey doesn't actually use multiple threads, it simulates some of that behavior: If a second thread is started -- such as by pressing another hotkey while the previous is still running -- the current thread will be interrupted (temporarily halted) to allow the new thread to become current. If a third thread is started while the second is still running, both the second and first will be in a dormant state, and so on.

When the current thread finishes, the one most recently interrupted will be resumed, and so on, until all the threads finally finish. When resumed, a thread's settings for things such as SendMode and SetKeyDelay are automatically restored to what they were just prior to its interruption; in other words, a thread will experience no side-effects from having been interrupted (except for a possible change in the active window).

Note: The KeyHistory function/menu-item shows how many threads are in an interrupted state and the ListHotkeys function/menu-item shows which hotkeys have threads.

A single script can have multiple simultaneous MsgBox, InputBox, FileSelect, and DirSelect dialogs. This is achieved by launching a new thread (via hotkey, timed subroutine, custom menu item, etc.) while a prior thread already has a dialog displayed.

By default, a given hotkey or hotstring subroutine cannot be run a second time if it is already running. Use #MaxThreadsPerHotkey to change this behavior.

Related: The Thread function sets the priority or interruptibility of threads.

Thread Priority

Any thread (hotkey, timed subroutine, custom menu item, etc.) with a priority lower than that of the current thread cannot interrupt it. During that time, such timers will not run, and any attempt by the user to create a thread (such as by pressing a hotkey or GUI button) will have no effect, nor will it be buffered. Because of this, it is usually best to design high priority threads to finish quickly, or use Critical instead of making them high priority.

The default priority is 0. All threads use the default priority unless changed by one of the following methods:
1) A timed subroutine is given a specific priority via SetTimer.
2) A hotkey is given a specific priority via the Hotkey function.
3) A hotstring is given a specific priority when it is defined, or via the #Hotstring directive.
4) A custom menu item is given a specific priority via the Menu.Add method.
5) The current thread sets its own priority via the Thread function.

The OnExit callback function (if any) will always run when called for, regardless of the current thread's priority.

Thread Interruptibility

For most types of events, new threads are permitted to launch only if the current thread is interruptible. A thread can be uninterruptible for a number of reasons, including:

Behavior of Uninterruptible Threads

Unlike high-priority threads, events that occur while the thread is uninterruptible are not discarded. For example, if the user presses a hotkey while the current thread is uninterruptible, the hotkey is buffered indefinitely until the current thread finishes or becomes interruptible, at which time the hotkey is launched as a new thread.

Any thread may be interrupted in emergencies. Emergencies consist of: 1) an OnExit callback; 2) any OnMessage function that monitors a message number less than 0x312 (or a callback triggered by such a message); and 3) any callback indirectly triggered by the thread itself (e.g. via SendMessage or DllCall). To avoid these interruptions, temporarily disable such functions.

A critical thread becomes interruptible when a MsgBox or other dialog is displayed. However, unlike Thread Interrupt, the thread becomes critical (and therefore uninterruptible) again after the user dismisses the dialog.