C# Mutex 总是卡在 WaitOne 上
C# Mutex always stuck on WaitOne
我有一个创建互斥量并立即取得所有权的进程,然后在单击按钮时释放它:
Mutex req_mutex = new Mutex(true, "req_mutex");
...
req_mutex.WaitOne(); // not required for first click
req_mutex.ReleaseMutex();
另一个进程正在循环检查互斥量是否存在,当它存在时等待它被释放:
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex", MutexRights.Synchronize);
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Thread.Sleep(1000);
}
}
...
req_mutex.WaitOne(); // wait for new request *********** problem here *********
req_mem.readFile(); // read request
req_mutex.ReleaseMutex(); // release req mutex for more requests
问题是即使在第一个进程中应该由按钮释放互斥体后,WaitOne 也没有继续。
有人知道为什么会这样吗?
我想我找到了自己问题的答案...
显然,您执行的 WaitOne 操作的数量确实很重要。
我获得了所有权(构造函数中的真实参数)并在同一线程中做了一个额外的 WaitOne 假设它不会受到伤害。
现在为了释放互斥锁,我显然不得不调用 ReleaseMutex 两次。
我想我仍然可以这样做并在循环中调用 ReleaseMutex 直到抛出异常...
我想如果你用 true 创建互斥量 (new Mutex(true, "req_mutex");
)
你不需要在那个过程中调用 WaitOne()
。
文档说调用此构造函数重载时最好将 initiallyOwned 指定为 false。 https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx
编辑:啊,你抢先了我 :) ...
您基本上是在第一个应用程序中获取了两次互斥量。您可以通过在第二个应用程序为 运行 时终止第一个应用程序来看到这一点,您将获得一个 AbandonedMutexException
(这意味着获得了 Mutex)。使用以下内容转载,而不是单击按钮:
namespace Mutex_1
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = new Mutex(true, "req_mutex");
String t = string.Empty;
while (!t.Contains("q"))
{
Console.WriteLine("input: ");
t = Console.ReadLine();
Console.WriteLine("waiting for req_mutex");
req_mutex.WaitOne(); // not required for first click
Console.WriteLine("releasing req_mutex");
req_mutex.ReleaseMutex();
}
Console.ReadLine();
}
}
}
namespace Mutex_2
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = null;
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex");
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("req_mutex does not exist.");
Thread.Sleep(1000);
}
}
Console.WriteLine("req_mutex found");
req_mutex.WaitOne(); // wait for new request *********** problem here *********
Console.WriteLine("after req_mutex.WaitOne()");
req_mutex.ReleaseMutex(); // release req mutex for more requests
Console.ReadLine();
}
}
}
此声明的更多证据:在父级中调用 ReleaseMutex
两次将使事情在第一次 "click" 上运行(并在第二次崩溃)。您可以通过在创建锁时不获取锁来解决此问题而不会引发异常:
Mutex req_mutex = new Mutex(false, "req_mutex");
我有一个创建互斥量并立即取得所有权的进程,然后在单击按钮时释放它:
Mutex req_mutex = new Mutex(true, "req_mutex");
...
req_mutex.WaitOne(); // not required for first click
req_mutex.ReleaseMutex();
另一个进程正在循环检查互斥量是否存在,当它存在时等待它被释放:
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex", MutexRights.Synchronize);
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Thread.Sleep(1000);
}
}
...
req_mutex.WaitOne(); // wait for new request *********** problem here *********
req_mem.readFile(); // read request
req_mutex.ReleaseMutex(); // release req mutex for more requests
问题是即使在第一个进程中应该由按钮释放互斥体后,WaitOne 也没有继续。
有人知道为什么会这样吗?
我想我找到了自己问题的答案...
显然,您执行的 WaitOne 操作的数量确实很重要。 我获得了所有权(构造函数中的真实参数)并在同一线程中做了一个额外的 WaitOne 假设它不会受到伤害。 现在为了释放互斥锁,我显然不得不调用 ReleaseMutex 两次。
我想我仍然可以这样做并在循环中调用 ReleaseMutex 直到抛出异常...
我想如果你用 true 创建互斥量 (new Mutex(true, "req_mutex");
)
你不需要在那个过程中调用 WaitOne()
。
文档说调用此构造函数重载时最好将 initiallyOwned 指定为 false。 https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx
编辑:啊,你抢先了我 :) ...
您基本上是在第一个应用程序中获取了两次互斥量。您可以通过在第二个应用程序为 运行 时终止第一个应用程序来看到这一点,您将获得一个 AbandonedMutexException
(这意味着获得了 Mutex)。使用以下内容转载,而不是单击按钮:
namespace Mutex_1
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = new Mutex(true, "req_mutex");
String t = string.Empty;
while (!t.Contains("q"))
{
Console.WriteLine("input: ");
t = Console.ReadLine();
Console.WriteLine("waiting for req_mutex");
req_mutex.WaitOne(); // not required for first click
Console.WriteLine("releasing req_mutex");
req_mutex.ReleaseMutex();
}
Console.ReadLine();
}
}
}
namespace Mutex_2
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = null;
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex");
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("req_mutex does not exist.");
Thread.Sleep(1000);
}
}
Console.WriteLine("req_mutex found");
req_mutex.WaitOne(); // wait for new request *********** problem here *********
Console.WriteLine("after req_mutex.WaitOne()");
req_mutex.ReleaseMutex(); // release req mutex for more requests
Console.ReadLine();
}
}
}
此声明的更多证据:在父级中调用 ReleaseMutex
两次将使事情在第一次 "click" 上运行(并在第二次崩溃)。您可以通过在创建锁时不获取锁来解决此问题而不会引发异常:
Mutex req_mutex = new Mutex(false, "req_mutex");