用于创建并初始化 临界区对象 的内置函数。
OutputVar := CriticalSection()函数示例: CriSec := CriticalSection()
用于存储指向临界区对象的指针的变量名称。
临界区对象在多线程环境中很有用(AutoHotkey.dll)。
临界区对象提供类似互斥对象的同步机制,但仅供单个进程内的线程使用。
当临界区已由一个线程拥有,而另一个线程尝试取得所有权时,后者会暂停等待,直到前一个线程释放所有权后才会继续。
要取得所有权,请调用 EnterCriticalSection(CriSec);要释放所有权,请调用 LeaveCriticalSection(CriSec)。如果不想锁定当前线程,使其仍能处理消息、热键、定时器等,也可以调用 TryEnterCriticalSection(CriSec)。
CriticalObject, AutoHotkey.dll
CriSec := CriticalSection() ; 创建并获取指向临界区对象的指针。
threadScript := "
(
CriSec := A_Args[1] ; 第一个命令行参数是指向临界区对象的指针。
Loop 5
{
EnterCriticalSection(CriSec) ; 取得所有权或等待直到可以。
MsgBox Critical Section is now owned by AutoHotkey.dll
LeaveCriticalSection(CriSec) ; 释放所有权。
; 留出一些时间让其他线程取得临界区的所有权。
; 如果不这样做,某些线程可能会饥饿。
Sleep(10)
}
)"
; 使用 AutoHotkey.dll 创建并启动线程
;命令行参数只能作为字符串传递。
;要转换指针(整数),请与空字符串连接。
AhkDllThread := AhkThread(threadScript, CriSec . "")
; 由主脚本线程执行的指令。
Loop 5
{
EnterCriticalSection(CriSec)
MsgBox Critical Section is now owned by AutoHotkey.exe
LeaveCriticalSection(CriSec)
Sleep(10)
}
EnterCriticalSection 尝试取得所有权的线程都会处于阻塞等待状态并发生饥饿。
CriSec := CriticalSection()
; 使用 AutoHotkey.dll 创建并启动线程
AhkDllThread := AhkThread("
(
CriSec := A_Args[1]
Loop 5
{
EnterCriticalSection(CriSec)
MsgBox Critical Section is now owned by AutoHotkey.dll
LeaveCriticalSection(CriSec)
; 该线程释放所有权后会尽快重新取得它,不给其他线程留下运行时间。
;尽管已经调用 EnterCriticalSection,其他线程仍会保持阻塞和等待。
}
)", CriSec . "")
; 此时 AhkDllThread 很可能已经被创建、启动,
;已取得临界区的所有权,并且当前正在显示五个消息框中的第一个。
Loop 5
{
; 在循环的第一次迭代中,主脚本线程尝试获取所有权。
;不能,因为 AhkDllThread 已经拥有所有权。
;主线程现在将阻塞,直到 AhkDllThread 释放其所有权。
;实际上,主线程必须等待 AhkDllThread 完成
;因为没有足够的时间来执行上下文切换。
EnterCriticalSection(CriSec)
MsgBox Critical Section is now owned by AutoHotkey.exe
LeaveCriticalSection(CriSec)
}
; 这种完全相同的情况很少会以相反的方式上演。