互斥对象

互斥对象是一个同步对象,当它不受任何线程拥有时,其状态设置为信号;当它拥有时,状态设置为信号。 一次只有一个线程可以拥有互斥对象,该对象的名称来自这样一个事实,即它有助于协调对共享资源的互斥访问。 例如,为了防止两个线程同时写入共享内存,每个线程先等待互斥对象的所有权,然后再执行访问内存的代码。 写入共享内存后,线程释放互斥对象。

线程使用 CreateMutexCreateMutexEx 函数创建互斥对象。 创建线程可以请求互斥对象的即时所有权,还可以指定互斥对象的名称。 它还可以创建未命名的互斥体。 有关互斥体、事件、信号量和计时器对象的名称的其他信息,请参阅 进程间同步

其他进程中的线程可以通过在调用 OpenMutex 函数时指定其名称来打开现有命名互斥对象句柄。 若要将句柄传递给未命名的互斥体到另一个进程,请使用 DuplicateHandle 函数或父子句柄继承。

具有互斥对象句柄的任何线程都可以使用 等待函数 之一来请求互斥对象的所有权。 如果互斥对象由另一个线程拥有,则 wait 函数会阻止请求线程,直到拥有的线程使用 ReleaseMutex 函数释放互斥对象。 wait 函数的返回值指示函数是否返回的原因,而不是设置为信号的互斥状态。

如果多个线程正在等待互斥体,则会选择一个正在等待的线程。 不要假定先入先出 (FIFO) 顺序。 外部事件(如内核模式 APC)可以更改等待顺序。

线程获得互斥体的所有权后,它可以在对 wait-functions 的重复调用中指定相同的互斥,而不会阻止其执行。 这可以防止线程在等待它已拥有的互斥体时自行死锁。 若要在此类情况下释放其所有权,每次互斥体满足等待函数的条件时,线程都必须调用 ReleaseMutex 一次。

如果线程终止而不释放其互斥对象的所有权,则互斥对象被视为已放弃。 等待线程可以获取已放弃互斥对象的所有权,但 wait 函数将返回 WAIT_ABANDONED 指示互斥对象已放弃。 放弃的互斥对象表示发生了错误,并且受互斥对象保护的任何共享资源都处于未定义状态。 如果线程像未放弃互斥对象一样继续,在线程释放其所有权后,不再将其视为已放弃。 如果随后在 wait 函数中指定互斥对象的句柄,这将还原正常行为。

请注意, 关键节对象 提供的同步类似于互斥对象提供的同步,只是关键节对象只能由单个进程的线程使用。

使用互斥对象