c++ - 多个互斥体上的 Windows 同步

标签 c++ winapi synchronization mutex waitformultipleobjects

我不太清楚,谁能帮我确认一下?

我有以下同步问题。我有以下对象:

A. Process 1, thread 1: Read & write access to the resource.
B. Process 1, thread 2: Read access to the resource.
C. Process 2, thread 3: Read access to the resource.

访问条件如下:

  1. 必须在 B 或 C 开启时阻止 A。
  2. B 必须仅在 A 开启时被阻止。
  3. C 必须仅在 A 开启时被阻止。

所以我想为此使用 2 个命名的互斥体:

  • hMutex2 = 用于满足上述条件 2。
  • hMutex3 = 用于满足上述条件 3。
  • hStopEvent = 停止事件(如果应用正在关闭,则需要停止线程)。

所以对于 A:

HANDLE hHandles[3] = {hMutex2, hMutex3, hStopEvent};
DWORD dwRes = WaitForMultipleObjects(3, hHandles, FALSE, INFINITE);
if(dwRes == WAIT_OBJECT_0 + 2)
{
    //Quit now
    return;
}
else if(dwRes == WAIT_OBJECT_0 + 0 ||
    dwRes == WAIT_OBJECT_0 + 1)
{
    //Do reading & writing here
    ...

    //Release ownership
    ReleaseMutex(hMutex2);
    ReleaseMutex(hMutex3);
}
else
{
    //Error
}

对于乙:

DWORD dwRes = WaitForSingleObject(hMutex2, INFINITE);
if(dwRes == WAIT_OBJECT_0)
{
    //Do reading here
    ...

    //Release ownership
    ReleaseMutex(hMutex2);
}
else
{
    //Error
}

对于 C:

DWORD dwRes = WaitForSingleObject(hMutex3, INFINITE);
if(dwRes == WAIT_OBJECT_0)
{
    //Do reading here
    ...

    //Release ownership
    ReleaseMutex(hMutex3);
}
else
{
    //Error
}

有人可以证实这一点吗:

  • 在两个互斥量上调用 WaitForMultipleObjects 时,它们是否都变为有信号(或阻塞)?
  • 我还需要释放两个互斥锁吗?

最佳答案

WaitForMultipleObjects当任何一个互斥体发出信号时,调用如写的那样(第三个参数为 FALSE)将返回。这意味着作者和其中一位读者可以同时访问资源。一个读者可能正在访问资源,而另一个读者释放其互斥量。届时,作者将获释。

所以要像那样使用两个互斥量,你需要等待它们。但是,您不能只将第三个参数设置为 TRUE,因为这意味着它还需要发出 hStopEvent 信号才能释放该线程(这显然是不需要的)。

一种可能是检查释放了哪个互斥锁,然后让编写器在继续之前等待另一个互斥锁。然后它需要在完成任务后释放它们。这种类型的解决方案的一个问题是它可能会很快变得复杂,如果您添加更多需要互斥锁的进程,如果不小心,您可能会陷入死锁。使用读写器类型的锁会大大简化处理过程。

编辑 这实际上并不是问题答案的一部分,但取决于所涉及的进程、它们访问资源的频率以及它们在访问资源时持有互斥量的时间,你可以通过使用一个互斥量并将其视为关键部分来真正简化它......每个进程在需要访问资源时都会获得它。但是,它当然不允许两个读取器线程/进程都具有并发访问权限,因此这可能会或可能不会被接受。但从长远来看,验证起来要容易得多。

关于c++ - 多个互斥体上的 Windows 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10963174/

相关文章:

c++ - 传递给 LogonUser() 的密码不正确,但 Active Directory 帐户未按预期锁定

c - 具有低/高字和低/高字节的 DWORD 变量

java - 我将如何在 Java 中实现 Go 的无缓冲 channel ?

c - 我如何使用屏障同步此代码?

c++ - Wav文件停止功能

c++ - VC++ win32 API编程 : how can I get the image out of the clipboard and display it in a windows?

c++ - .访问违规读取位置

java - 我怎样才能重写这个主线程 - 工作线程同步

c++ - 是否有一种模式可以跟踪容器中当前选定的项目? state 适合这里吗?

c++ - 包含 MVTec Halcon 库时未声明的标识符