对 CreateMutex 的困惑

Posted

技术标签:

【中文标题】对 CreateMutex 的困惑【英文标题】:Confusion on CreateMutex 【发布时间】:2011-02-25 10:04:44 【问题描述】:

假设我调用 CreateMutex。

HANDLE h;
h=CreateMutex(NULL, TRUE, NULL);
waitforsingleobject(h, INFINITE);
////Random Code
ReleaseMutex(h);

假设我有多个线程正在运行,第一个到达函数 createmutex 的线程实际上会阻塞 //random 代码部分中的所有其他线程,直到调用 release mutex 对吗?

【问题讨论】:

如果这种锁定是针对单个进程中的线程,您是否意识到使用临界区会更好? 【参考方案1】:

它没有,因为您创建了一个未命名的互斥体(第三个参数是名称)。假设示例代码在多个线程中运行,每个线程将创建一个新的未命名互斥体,并会立即访问临界区(随机代码),因为它们只等待自己的互斥体。

要解决这个问题,或者让 h 成为所有线程都可以访问的全局句柄,并在共享代码之外调用 CreateMutex,或者为 CreateMutex 提供一个名称(第三个参数)。在后一种情况下,对 CreateMutex 的后续调用将返回现有互斥锁的句柄。

【讨论】:

【参考方案2】:

由于您没有为互斥锁指定名称,因此每个线程都会创建自己不同的互斥锁,其他线程不会知道。

在您的场景中,关键部分将是更好的选择。

【讨论】:

【参考方案3】:

考虑到您创建了一个未命名的互斥锁,每个线程将创建一个自己的未命名互斥锁并在创建时承担所有权。由于每个线程都有自己的互斥体,所有线程都可以并行运行。

因此,如果您希望它不被命名,您应该为所有线程创建一次互斥锁。通过查看您的代码,您还应该检查互斥锁创建是否成功。

然后在从多个线程调用的函数中调用之前创建的互斥体上的 WaitForSingleObject。

检查返回的结果是因为您获得了互斥锁的所有权还是因为放弃了互斥锁而终止了等待。

如果您有所有权,请确保在互斥体句柄上调用 ReleaseMutex。出于多种原因,您可能应该考虑使用 RAII 来管理互斥锁(以确保在发生异常或在 ReleaseMutex 之前插入 return 语句时正确释放互斥锁等等)。

当不再需要互斥体时,请确保在 MutexHandle 上调用 CloseHandle。

有关如何使用互斥锁的示例,请参见此处:"Using Mutex Objects"

有关基本的多线程包装,请参见此处:Using Threads

【讨论】:

【参考方案4】:

仅当所有线程/进程共享相同的互斥量引用时。你不是在分享它,而是每次都在创造它。您需要为其命名,以便它们都获得相同的互斥锁以使您的代码正常工作。

【讨论】:

以上是关于对 CreateMutex 的困惑的主要内容,如果未能解决你的问题,请参考以下文章

如何从.Net调用win32 CreateMutex

CreateMutex函数 (转)

CreateMutex和WaitForSingleObject组合的有关问题

CreateMutex()参数问题

Delphi CreateMutex 防止程序多次运行

CreateMutex 从不返回 ERROR_ALREADY_EXISTS