C#中的锁和互斥锁是否应该一起使用

时间:2009-03-13 15:13:13

标签: c# locking mutex

这不是矫枉过正,只有其中一项必要吗?我搜索过并发现了有关互斥的不同帖子以及C#herehere中的锁定。

例如:
在我们的应用程序中,我们有一个旋转多个重新连接线程的函数,在这个线程中我们使用Mutexlock。不会lock阻止访问此部分代码并阻止connect被任何其他线程更新?

bool connect = false;
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key);

try
{
   lock(site)
   {
      if(site.ContainsKey(key))
      {
         siteInfo = (SiteInfo)site[key];
         if(reconnectMutex.WaitOne(100, true))
         {
            connect = true;
         }
      }
   }

   if (connect)
   { 
      // Process thread logic
   }
}
catch
{}

reconnectMutex.ReleaseMutex();

更多信息:
这是在不在Web Garden中运行的ASP.NET WebService中。

4 个答案:

答案 0 :(得分:11)

Mutex(因为它有一个名字)将停止访问它的同一台机器上的任何进程,而lock只会停止同一进程中的其他线程。我无法从该代码示例中看到为什么您需要这两种锁。在短时间内保持简单锁定似乎是一种好习惯 - 但是更重的进程间互斥锁被锁定的时间可能更长(虽然重叠)!使用互斥锁会更简单。也许要找出是否真的需要进程间锁。

顺便说一句,在这种情况下使用catch {}绝对是错误的。您应该使用finally { /* release mutex */ }。他们是非常不同的。 catch会吞下更多种类的异常,并且还会导致嵌套的finally处理程序执行以响应低级异常,例如内存损坏,访问冲突等。所以代替:

try
{
    // something
}
catch
{}

// cleanup

你应该:

try
{
    // something
}
finally
{
    // cleanup
}

如果您可以从中恢复特定的例外,您可以抓住它们:

try
{
    // something
}
catch (DatabaseConfigurationError x)
{
    // tell the user to configure the database properly
}
finally
{
    // cleanup
}

答案 1 :(得分:3)

“lock”基本上只是Montor.Enter / Exit的语法糖。 Mutex是一个多进程锁。

他们的行为非常不同。在同一个应用程序或方法中使用它们没有任何问题,因为它们旨在阻止不同的事物。

但是,在你的情况下,我认为你可能会更好地研究Semaphore和Monitor。听起来你不需要锁定进程,因此在这种情况下它们可能是更好的选择。

答案 2 :(得分:2)

正如其他人所指出的,Mutex跨进程锁定,本地锁(Monitor)仅锁定当前进程拥有的那些线程。但是......

您展示的代码有一个非常严重的错误。看起来你最后无条件释放了Mutex(即reconnectMutex.ReleaseMutex()),但只有当site.ContainsKey()返回true时才会获取互斥锁。

因此,如果site.ContainsKey返回false,则释放互斥锁会抛出ApplicationException,因为调用线程不拥有互斥锁。

答案 3 :(得分:1)

你没有提供足够的信息来真正回答这个问题。正如Earwicker已经说明的那样,Mutex允许您在进程间进行同步。因此,如果您运行同一个应用程序的两个实例,则可以序列化访问。例如,在使用外部资源时,您可以执行此操作。

现在,您锁定站点可以保护站点不被同一进程中的其他线程访问。这可能是nessecary,具体取决于其他方法/线程正在做什么。现在,如果这是唯一一个网站被锁定的地方,那么我认为这是过度杀伤。