</head> <body> <h1>Threads</h1> <p>The <em>current thread</em> is defined as the flow of execution invoked by the most recent event; examples include <a href="../Hotkeys.htm">hotkeys</a>, <a href="../commands/SetTimer.htm">SetTimer subroutines</a>, <a href="../commands/Menu.htm">custom menu items</a>, and <a href="../commands/Gui.htm#Events">GUI events</a>. The <em>current thread</em> can be executing commands within its own subroutine or within other subroutines called by that subroutine.</p> <p>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 <em>current thread</em> will be interrupted (temporarily halted) to allow the new thread to become <em>current</em>. 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.</p> <p>When the <em>current thread</em> 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 <a href="ErrorLevel.htm">ErrorLevel</a> and <a href="../commands/SendMode.htm">SendMode</a> 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 <a href="../commands/WinActivate.htm">active window</a>).</p> <p class="note"><strong>Note</strong>: The <a href="../commands/KeyHistory.htm">KeyHistory</a> command/menu-item shows how many threads are in an interrupted state and the <a href="../commands/ListHotkeys.htm">ListHotkeys</a> command/menu-item shows which hotkeys have threads.</p> <p>A single script can have multiple simultaneous <a href="../commands/MsgBox.htm">MsgBox</a>, <a href="../commands/InputBox.htm">InputBox</a>, <a href="../commands/FileSelectFile.htm">FileSelectFile</a>, and <a href="../commands/FileSelectFolder.htm">FileSelectFolder</a> dialogs. This is achieved by launching a new thread (via <a href="../Hotkeys.htm">hotkey</a>, <a href="../commands/SetTimer.htm">timed subroutine</a>, <a href="../commands/Menu.htm">custom menu item</a>, etc.) while a prior thread already has a dialog displayed.</p> <p>By default, a given <a href="../Hotkeys.htm">hotkey</a> or <a href="../Hotstrings.htm">hotstring</a> subroutine cannot be run a second time if it is already running. Use <a href="../commands/_MaxThreadsPerHotkey.htm">#MaxThreadsPerHotkey</a> to change this behavior.</p> <p><strong>Related:</strong> The <a href="../commands/Thread.htm">Thread</a> command sets the priority or interruptibility of threads.</p> <h2 id="Priority">Thread Priority</h2> <p>Any thread (<a href="../Hotkeys.htm">hotkey</a>, <a href="../commands/SetTimer.htm">timed subroutine</a>, <a href="../commands/Menu.htm">custom menu item</a>, etc.) with a priority lower than that of the <em>current thread</em> 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 <a href="../Hotkeys.htm">hotkey</a> or <a href="../commands/GuiControls.htm#Button">GUI button</a>) 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 <a href="../commands/Critical.htm">Critical</a> instead of making them high priority.</p> <p>The default priority is 0. All threads use the default priority unless changed by one of the following methods:</p> <ul> <li>A timed subroutine is given a specific priority via <a href="../commands/SetTimer.htm">SetTimer</a>.</li> <li>A hotkey is given a specific priority via the <a href="../commands/Hotkey.htm">Hotkey</a> command.</li> <li>A <a href="../Hotstrings.htm">hotstring</a> is given a specific priority when it is defined, or via the <a href="../commands/_Hotstring.htm">#Hotstring</a> directive.</li> <li>A custom menu item is given a specific priority via the <a href="../commands/Menu.htm">Menu</a> command.</li> <li>The <em>current thread</em> sets its own priority via the <a href="../commands/Thread.htm">Thread</a> command.</li> </ul> <p>The <a href="../commands/OnExit.htm">OnExit</a> thread (if any) will always run when called for, regardless of the <em>current thread</em>'s priority.</p> <h2 id="Interrupt">Thread Interruptibility</h2> <p>For most types of events, new threads are permitted to launch only if the current thread is <em>interruptible</em>. A thread can be <em>uninterruptible</em> for a number of reasons, including:</p> <ul> <li>The thread has been marked as <em>critical</em>. <a href="../commands/Critical.htm">Critical</a> may have been called by the thread itself or from within the <a href="../Scripts.htm#auto">auto-execute section</a>.</li> <li>The thread has not been running long enough to meet the conditions for becoming interruptible, as set by <a href="../commands/Thread.htm#Interrupt">Thread Interrupt</a>.</li> <li>One of the script's menus is being displayed (such as the tray icon menu or a menu bar).</li> <li>A delay is being performed by <a href="../commands/Send.htm">Send</a> (most often due to <a href="../commands/SetKeyDelay.htm">SetKeyDelay</a>), <a href="../commands/WinActivate.htm">WinActivate</a>, or a <a href="Clipboard.htm">Clipboard</a> operation.</li> <li>An <a href="../commands/OnExit.htm">OnExit</a> thread is executing.</li> <li>A warning dialog is being displayed due to the <a href="../commands/_MaxHotkeysPerInterval.htm">#MaxHotkeysPerInterval</a> limit being reached, or due to a problem activating the keyboard or mouse hook (very rare).</li> </ul> <h3 id="Behave">Behavior of Uninterruptible Threads</h3> <p>Unlike high-priority threads, events that occur while the thread is uninterruptible are not discarded. For example, if the user presses a <a href="../Hotkeys.htm">hotkey</a> 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.</p> <p>Any thread may be interrupted in emergencies. Emergencies consist of: 1) an <a href="../commands/OnExit.htm#function">OnExit</a> callback; 2) any <a href="../commands/OnMessage.htm">OnMessage</a> function that monitors a message number less than 0x0312 (or a <a href="../commands/RegisterCallback.htm">callback</a> triggered by such a message); and 3) any <a href="../commands/RegisterCallback.htm">callback</a> indirectly triggered by the thread itself (e.g. via <a href="../commands/PostMessage.htm">SendMessage</a> or <a href="../commands/DllCall.htm">DllCall</a>). To avoid these interruptions, temporarily disable such functions.</p> <p>A <a href="../commands/Critical.htm">critical</a> thread becomes interruptible when a <a href="../commands/MsgBox.htm">MsgBox</a> or other dialog is displayed. However, unlike <a href="../commands/Thread.htm">Thread Interrupt</a>, the thread becomes critical (and therefore uninterruptible) again after the user dismisses the dialog.</p> </body> </html>