스레드
스레드 (Threads)
AutoHotkey에서 현재 스레드(current thread)의 개념, 스레드 우선순위, 그리고 스레드 중단 가능성(interruptibility)을 설명하는 문서예요.
출처: 문서
본문
*현재 스레드(current thread)*는 가장 최근의 이벤트가 호출한 실행 흐름으로 정의돼요. 예로는 핫키, SetTimer 서브루틴, 사용자 정의 메뉴 항목, GUI 이벤트가 있어요. 현재 스레드는 자체 서브루틴 안에서 또는 그 서브루틴이 호출한 다른 서브루틴 안에서 함수를 실행할 수 있어요.
AutoHotkey가 실제로 여러 스레드를 사용하지는 않지만, 그 동작의 일부를 흉내 내요. 두 번째 스레드가 시작된다면(예: 이전 스레드가 여전히 실행 중일 때 다른 핫키를 누르는 경우), 현재 스레드는 새 스레드가 현재 스레드가 되도록 방해받고(일시적으로 중단)돼요. 두 번째 스레드가 여전히 실행 중일 때 세 번째 스레드가 시작되면, 두 번째와 첫 번째가 모두 휴면 상태가 되는 식이에요.
현재 스레드가 끝나면, 가장 최근에 방해받은 스레드가 재개되고, 모든 스레드가 마침내 끝날 때까지 이런 식으로 계속돼요. 재개될 때 SendMode나 SetKeyDelay 같은 것들에 대한 스레드의 설정은 방해받기 직전의 상태로 자동 복원돼요. 즉, 스레드는 (활성 창의 가능한 변경을 제외하면) 방해받은 것에 대한 부작용을 경험하지 않아요.
참고: KeyHistory 함수/메뉴 항목은 방해 상태에 있는 스레드가 몇 개인지 보여주고, ListHotkeys 함수/메뉴 항목은 어떤 핫키에 스레드가 있는지 보여줘요.
단일 스크립트는 여러 동시 MsgBox, InputBox, FileSelect 및 DirSelect 대화 상자를 가질 수 있어요. 이전 스레드가 이미 대화 상자를 표시하고 있는 동안 (핫키, 타이머 서브루틴, 사용자 정의 메뉴 항목 등으로) 새 스레드를 시작하면 달성할 수 있어요.
기본적으로, 주어진 핫키나 핫스트링 서브루틴은 이미 실행 중이면 두 번째로 실행될 수 없어요. 이 동작을 바꾸려면 #MaxThreadsPerHotkey를 사용해요.
관련: Thread 함수는 스레드의 우선순위나 중단 가능성을 설정해요.
스레드 우선순위 (Thread Priority)
현재 스레드보다 낮은 우선순위를 가진 어떤 스레드도(핫키, 타이머 서브루틴, 사용자 정의 메뉴 항목 등) 그것을 방해할 수 없어요. 그동안 그러한 타이머는 실행되지 않으며, 사용자가 (핫키나 GUI 버튼을 누르는 등으로) 스레드를 만들려고 시도해도 아무 효과가 없고 버퍼링되지도 않아요. 이 때문에 높은 우선순위 스레드는 빠르게 끝나도록 설계하거나, 높은 우선순위로 만드는 대신 Critical을 사용하는 것이 보통 가장 좋아요.
기본 우선순위는 0이에요. 다음 방법 중 하나로 변경하지 않는 한 모든 스레드는 기본 우선순위를 사용해요:
- 타이머 서브루틴에 SetTimer로 특정 우선순위가 주어짐.
- 핫키에 Hotkey 함수로 특정 우선순위가 주어짐.
- 핫스트링이 정의될 때 또는
#Hotstring지시문으로 특정 우선순위가 주어짐. - 사용자 정의 메뉴 항목에 Menu.Add 메서드로 특정 우선순위가 주어짐.
- 현재 스레드가 Thread 함수로 자신의 우선순위를 설정함.
OnExit 콜백 함수는(있다면) 현재 스레드의 우선순위와 무관하게 호출될 때마다 항상 실행돼요.
스레드 중단 가능성 (Thread Interruptibility)
대부분의 이벤트 유형에서, 새 스레드는 현재 스레드가 *중단 가능(interruptible)*할 때만 시작될 수 있어요. 스레드는 여러 이유로 *중단 불가능(uninterruptible)*할 수 있어요:
- 스레드가 critical(중요)로 표시됨. Critical은 스레드 자체나 자동 실행(auto-execute) 스레드가 호출했을 수 있어요.
- 스레드가 Thread Interrupt가 설정한 중단 가능해지기 위한 조건을 충족할 만큼 충분히 오래 실행되지 않음.
- 스크립트의 메뉴 중 하나가 표시 중임(트레이 아이콘 메뉴나 메뉴 바 같은 것).
- Send(가장 흔히 SetKeyDelay 때문에), WinActivate, 또는 클립보드 작업으로 지연이 수행 중임.
- OnExit 스레드가 실행 중.
A_MaxHotkeysPerInterval제한에 도달했거나 키보드/마우스 훅 활성화에 문제가 있어(매우 드묾) 경고 대화 상자가 표시 중.
중단 불가능한 스레드의 동작 (Behavior of Uninterruptible Threads)
높은 우선순위 스레드와 달리, 스레드가 중단 불가능할 때 발생하는 이벤트는 버려지지 않아요. 예를 들어, 현재 스레드가 중단 불가능할 때 사용자가 핫키를 누르면, 현재 스레드가 끝나거나 중단 가능해질 때까지 그 핫키가 무한정 버퍼링되고, 그 시점에 핫키가 새 스레드로 시작돼요.
어떤 스레드라도 긴급 상황에서는 중단될 수 있어요. 긴급 상황은 다음과 같아요:
- OnExit 콜백.
- 버퍼링되지 않는 메시지를 모니터링하는 OnMessage 함수.
- 스레드 자체가 간접적으로 트리거한 콜백(예: SendMessage 또는 DllCall을 통해).
이런 중단을 피하려면 그러한 함수를 일시적으로 비활성화해요.
critical 스레드는 MsgBox나 다른 대화 상자가 표시될 때 중단 가능해져요. 다만 Thread Interrupt와 달리, 사용자가 대화 상자를 닫은 후에는 스레드가 다시 critical(따라서 중단 불가능)이 돼요.