互斥对象
互斥对象是一个同步对象,当它不受任何线程拥有时,其状态设置为信号;当它拥有时,状态设置为信号。 一次只有一个线程可以拥有互斥对象,该对象的名称来自这样一个事实,即它有助于协调对共享资源的互斥访问。 例如,为了防止两个线程同时写入共享内存,每个线程先等待互斥对象的所有权,然后再执行访问内存的代码。 写入共享内存后,线程释放互斥对象。
线程使用 CreateMutex 或 CreateMutexEx 函数创建互斥对象。 创建线程可以请求互斥对象的即时所有权,还可以指定互斥对象的名称。 它还可以创建未命名的互斥体。 有关互斥体、事件、信号量和计时器对象的名称的其他信息,请参阅 进程间同步。
其他进程中的线程可以通过在调用 OpenMutex 函数时指定其名称来打开现有命名互斥对象句柄。 若要将句柄传递给未命名的互斥体到另一个进程,请使用 DuplicateHandle 函数或父子句柄继承。
具有互斥对象句柄的任何线程都可以使用 等待函数 之一来请求互斥对象的所有权。 如果互斥对象由另一个线程拥有,则 wait 函数会阻止请求线程,直到拥有的线程使用 ReleaseMutex 函数释放互斥对象。 wait 函数的返回值指示函数是否返回的原因,而不是设置为信号的互斥状态。
如果多个线程正在等待互斥体,则会选择一个正在等待的线程。 不要假定先入先出 (FIFO) 顺序。 外部事件(如内核模式 APC)可以更改等待顺序。
线程获得互斥体的所有权后,它可以在对 wait-functions 的重复调用中指定相同的互斥,而不会阻止其执行。 这可以防止线程在等待它已拥有的互斥体时自行死锁。 若要在此类情况下释放其所有权,每次互斥体满足等待函数的条件时,线程都必须调用 ReleaseMutex 一次。
如果线程终止而不释放其互斥对象的所有权,则互斥对象被视为已放弃。 等待线程可以获取已放弃互斥对象的所有权,但 wait 函数将返回 WAIT_ABANDONED 指示互斥对象已放弃。 放弃的互斥对象表示发生了错误,并且受互斥对象保护的任何共享资源都处于未定义状态。 如果线程像未放弃互斥对象一样继续,在线程释放其所有权后,不再将其视为已放弃。 如果随后在 wait 函数中指定互斥对象的句柄,这将还原正常行为。
请注意, 关键节对象 提供的同步类似于互斥对象提供的同步,只是关键节对象只能由单个进程的线程使用。
相关主题