2012-06-09 56 views
0

我不清楚这件事,有人可以证实这一点吗?多个互斥体上的Windows同步

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

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. 

而这里的准入条件:

而B或C在
  1. A必须被阻止。
  2. 只有A打开时,B才能被阻塞。
  3. 仅当A打开时,C必须被阻止。

所以我想使用2个名为互斥:

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

所以对于一个:

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 
} 

对于B:

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时,它们是否都变成了信号(或阻塞)?
  • 我也需要释放这两个互斥体吗?
+0

你想要一个“读写器”锁。如果内存服务,则可以在不使用WaitForMultipleObjects的情况下完成。 (你可能需要WaitFSO)。我会看看我能否在今天晚些时候发现它的实现。在此之前,Bing用于“读写器锁定” – selbie

回答

0

事实上,我可以反驳它。 WaitForMultipleObjectswaitAll参数设置为FALSE将返回如果任何的信号发送。 Here's the documentation :)将其设置为TRUE,然后您将等待全部对象。

您的解决方案不能很好地扩展,虽然:添加另一个读线程,和你坚持第三互斥...

Writer/Readers problem已经解决过很多次,但是,为什么不看看现有的实现?将为您节省大量调试时间,特别是如果您还不熟悉Windows同步API。 (Teaser:posix线程有一个readwritelock,提升有shared_mutex。)

+0

正如Mark的评论所指出的,设置为“TRUE”不起作用,因为它也会等待“hStopEvent”。 –

+0

@雷蒙德陈:确实; '你想要的'有些过分乐观,我承认:) – xtofl

+0

那么WinAPI用于该读写器锁定的任何想法? – ahmd0

1

当任何一个互斥信号被发信号时,将调用写为(第三个参数为FALSE)的WaitForMultipleObjects。这意味着作者和其中一个读者可以同时获得资源。一个阅读器可以访问资源,而另一个阅读器释放它的互斥体。那时,作家将被释放。

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

一种可能性可能是检查哪个互斥体被释放,然后让作者等待另一个互斥体,然后再继续。然后在完成任务后需要释放他们两个。这种类型的解决方案存在的一个问题是,它可能会很快变得复杂,如果您添加更多需要互斥锁的进程,那么如果您不小心,最终可能会发生死锁。使用读写器类型的锁可以简化处理过程。

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

+0

感谢您的解释。这一切都有道理。我想现在我会尝试搜索WinAPI的“读写器锁定”。我很高兴在我开始实施它之前将它发布在这里... – ahmd0

+0

我假设有一些可用,但我没有推荐。根据Jeffrey Richter出席的演讲,我最终为C写了一个读写器锁。写我自己的文章可能很愚蠢,但它已经由我的同事进行了同行评审,并且可能用了10年......所以我认为这是行得通的。不过,我不会推荐自己写。弄错它真的很容易。我当时无法找到一个可以公开使用的应用程序,可以用于当时我必须处理的三个不同操作系统。 –

+0

在我的情况下,读取操作比写入操作更频繁,因此,如果我只为它们使用单​​个互斥量,它会减慢速度。至于找到这个读写锁的实现,我一直得到的是当他们使用关键部分并且没有办法通过停止事件方法停止等待线程。 – ahmd0

0

你在找什么是读写器锁。在你的算法中,存在一个严重的问题 - 过程A的匮乏:如果B和C继续工作并接受它们的互斥体,则A可能无法进入。

+0

谢谢。说得通。 – ahmd0