互斥量时如何避免竞争条件?
作者:互联网
我正在使用一个命名的系统互斥锁来同步2个进程.这是我目前在应用程序中获取互斥量的方式:
using System.Threading;
public static bool AcquireMutex()
{
// Protect against double acquisitions
if (MyMutex != null)
{
throw new ApplicationException("Failed to acquire mutex");
}
try
{
// See if a named system mutex has already been created - if it has,
// wait a short amount of time for its release.
MyMutex = Mutex.OpenExisting(MutexName);
if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false))
{
// MyMutex still being held
MyMutex = null;
return false;
}
}
catch
{
// MyMutex doesn't exist so create it
MyMutex = new Mutex(true, MutexName);
}
return true;
}
如果具有MutexName的命名系统互斥锁不存在,OpenExisting将引发异常,从而允许我的应用程序创建它.
但是,这里似乎存在竞争条件-如果OpenExisting抛出,则在调用新Mutex之前会有一个小窗口,其他应用程序可能已在该窗口中获取了互斥体.
避免这种竞争情况并使此代码更可靠的最佳方法是什么?
一位同事提到他在代码中使用了Win32 Platform SDK中的CreateMutex(另一个需要同步的过程).但是,.NET Framework似乎并未对此提供支持.所以我不确定这是我代码的最佳解决方案.
更新资料
根据@David Schwartz的回答,这是我的新代码:
public static bool AcquireMutex()
{
// Protect against double acquisitions
if (MyMutex != null)
{
throw new ApplicationException("Failed to acquire mutex");
}
bool createdNew;
MyMutex = new Mutex(true, MutexName, out createdNew);
if (createdNew)
{
// Mutex was created so ownership is guaranteed; no need to wait on it.
return true;
}
try
{
if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false))
{
MyMutex = null;
return false;
}
}
catch (AbandonedMutexException)
{
// Other application was aborted, which led to an abandoned mutex.
// This is fine, as we have still successfully acquired the mutex.
}
return true;
}
解决方法:
有一个专门为此目的设计的构造函数.从docs:
createdNew
Type: System.Boolean
When this method returns, contains a Boolean that is true if a local mutex was created (that is, if name is null or an empty string) or if the specified named system mutex was created; false if the specified named system mutex already existed. This parameter is passed uninitialized.
标签:mutex,race-condition,c,net 来源: https://codeday.me/bug/20191101/1985678.html