所谓句柄(Handle),其实就是指针,指向操作系统内存空间中的某样东西,为了维护系统的完整性与安全性,不允许直接取得。
内核对象与GDI对象不同,内核对象由KERNEL32.DLL管理,而GDI对象由GDI32.DLL管理,另外GDI对象只有单一拥有者,不是进程就是线程,而内核对象可以有一个以上的拥有者,甚至可以跨进程。
WIN32中包含以下几类内核对象:
1. WaitForSingleObject()函数
DWORD WaitForSingleObject(
HANDLE handle,
DWORD dwMilliseconds
);
参数
handle: 等待的内核对象句柄
dwMilliseconds: 等待的最长时间,0代表立即返回,INFINITE代表无限等待
返回值
1. 内核对象变为激发状态,返回WAIT_OBJECT_0
2. 内核对象未激发而等待时间已到,返回WAIT_TIMEOUT
3. 等待的互斥器未被释放,返回WAIT_ABANDONED
4. 函数调用失败,返回WAIT_FAILED
2. WaitForMultipleObjects()函数
DWORD WaitForMultipleObjects(
DWORD nCount,
CONST HANDLE *lpHanldes,
BOOL bWaitAll,
DWORD dwMilliseconds
);
参数
nCount: lpHanldes所指数组的元素个数,最大值为MAXIMUM_WAIT_OBJECTS
lpHanles: 对象句柄数组
bWaitAll: 为TRUE时,所有等待对象都被激发函数才返回,否则,任一等待对象被激发函数就返回
dwMilliseconds: 最长等待时间
返回值
1. 内核对象未被激发但等待时间已到,返回值为WAIT_TIMEOUT
2. bWaitAll为TRUE,返回值将是WAIT_OBJECT_0
3. bWaitAll为FALSE,返回值减去WAIT_OBJECT_0,表示数组中第几个元素被激发
4. 等待的对象中有互斥器,返回值的范围为[WAIT_ABANDONED_0, WAIT_ABANDONED_0 + nCount - 1]
3. MsgWaitForMultipleObjects()函数
DWORD MsgWaitForMultipleObjects(
参数
dwWakeMake: 等待的用户输入消息,包括QS_ALLINPUT, QS_HOTKEY, QS_INPUT, QS_KEY, QS_MOUSE, QS_MOUSEBUTTON, QS_MOUSEMOVE, QS_PAINT, QS_POSTMESSAGE, QS_SENDMESSAGE, QS_TIMER
返回值
WAIT_OBJECT_0 + nCount,代表消息到达
同步机制
1. Critical Section
临界区用来实现“排他性占有”,适用范围是单一进程的各线程之间,它是:
2. Mutex
互斥器是一个内核对象,可以在不同的进程的线程间实现“排他性占有”,它是
3. Semaphore
信号量用来追踪有限的资源,它是
4. Event Object
事件对象通常使用于overlapped I/O,或用来设计某些自定义的同步对象,它是
5. Interlocked Variable
互锁变量主要用于引用计数,它们:
内核对象与GDI对象不同,内核对象由KERNEL32.DLL管理,而GDI对象由GDI32.DLL管理,另外GDI对象只有单一拥有者,不是进程就是线程,而内核对象可以有一个以上的拥有者,甚至可以跨进程。
WIN32中包含以下几类内核对象:
- 进程(Processes)
- 线程(Threads)
- 文件(File)
- 事件(Events)
- 信号量(Semaphores)
- 互斥器(Mutexes)
- 管道(Pipes)
表1 内核对象激发状态的意义
对象 | 说明 |
线程 | 线程结束时,线程对象被激发,线程运行时,线程对象处于未激发状态 |
进程 | 进程结束时,进程对象被激发,进行运行时,进程对象处于未激发状态 |
命令行输入 | 当命令行窗口的输入缓冲区中有数据时,命令行输入对象处于激发状态 |
Event | 事件对象由函数SetEvent(),PulseEvent()和ResetEvent()控制 |
Mutex | 没有任何拥有者时,互斥器对象处于激发状态,当线程中的等待函数返回时,互斥器对象被该线程所拥有,保持未激发状态,直到它被释放。 |
Semaphore | 具有计数器的互斥器对象,计数器大于0时,信号量对象被激发,等于0时处理未激发状态。 |
1. WaitForSingleObject()函数
DWORD WaitForSingleObject(
HANDLE handle,
DWORD dwMilliseconds
);
参数
handle: 等待的内核对象句柄
dwMilliseconds: 等待的最长时间,0代表立即返回,INFINITE代表无限等待
返回值
1. 内核对象变为激发状态,返回WAIT_OBJECT_0
2. 内核对象未激发而等待时间已到,返回WAIT_TIMEOUT
3. 等待的互斥器未被释放,返回WAIT_ABANDONED
4. 函数调用失败,返回WAIT_FAILED
2. WaitForMultipleObjects()函数
DWORD WaitForMultipleObjects(
DWORD nCount,
CONST HANDLE *lpHanldes,
BOOL bWaitAll,
DWORD dwMilliseconds
);
参数
nCount: lpHanldes所指数组的元素个数,最大值为MAXIMUM_WAIT_OBJECTS
lpHanles: 对象句柄数组
bWaitAll: 为TRUE时,所有等待对象都被激发函数才返回,否则,任一等待对象被激发函数就返回
dwMilliseconds: 最长等待时间
返回值
1. 内核对象未被激发但等待时间已到,返回值为WAIT_TIMEOUT
2. bWaitAll为TRUE,返回值将是WAIT_OBJECT_0
3. bWaitAll为FALSE,返回值减去WAIT_OBJECT_0,表示数组中第几个元素被激发
4. 等待的对象中有互斥器,返回值的范围为[WAIT_ABANDONED_0, WAIT_ABANDONED_0 + nCount - 1]
3. MsgWaitForMultipleObjects()函数
DWORD MsgWaitForMultipleObjects(
DWORD nCount,
LPHANDLE pHandles,
BOOL fWaitAll,
DWORD dwMilliseconds,
DWORD dwWakeMask
);LPHANDLE pHandles,
BOOL fWaitAll,
DWORD dwMilliseconds,
DWORD dwWakeMask
参数
dwWakeMake: 等待的用户输入消息,包括QS_ALLINPUT, QS_HOTKEY, QS_INPUT, QS_KEY, QS_MOUSE, QS_MOUSEBUTTON, QS_MOUSEMOVE, QS_PAINT, QS_POSTMESSAGE, QS_SENDMESSAGE, QS_TIMER
返回值
WAIT_OBJECT_0 + nCount,代表消息到达
同步机制
1. Critical Section
临界区用来实现“排他性占有”,适用范围是单一进程的各线程之间,它是:
- 一个局部对象,不是内核对象
- 快速而有效
- 不能够同时有一个以上的临界区被等待
- 无法检测是否已被某个线程放弃
2. Mutex
互斥器是一个内核对象,可以在不同的进程的线程间实现“排他性占有”,它是
- 一个内核对象
- 如果拥有互斥器的线程结束,则会产生一个错误消息
- 可以使用Wait…() 函数进行等待
- 可以命名,以便其它进程开启
- 只能被拥有它的线程释放
3. Semaphore
信号量用来追踪有限的资源,它是
- 一个内核对象
- 没有拥有者
- 可以命名,以便其它进程开启
- 可能被任何一个线程释放
4. Event Object
事件对象通常使用于overlapped I/O,或用来设计某些自定义的同步对象,它是
- 一个内核对象
- 完全受控于程序
- 适用于设计新的同步对象
- “唤醒”的请求并不会被存储,可能会丢失
- 可以命名,以便其它进程开启
5. Interlocked Variable
互锁变量主要用于引用计数,它们:
- 允许对4字节的数值有些基本的同步操作,不需要使用临界区或互斥器
- 在SMP操作系统中也能正常使用