我有一个创建互斥锁并立即获得所有权的进程,然后当单击一个按钮时,它会释放它:
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也不会继续。
有谁知道为什么会这样?
答案 0 :(得分:2)
我认为如果你用true(new Mutex(true, "req_mutex");
)创建互斥锁
您不应该在该过程中致电WaitOne()
。
文档说最好在调用此构造函数重载时为initialOwned指定false。 https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx
编辑:啊,你打败了我:) ...答案 1 :(得分:1)
您基本上是在第一次应用程序中两次获取互斥锁。你可以通过在第二个应用程序运行时杀死你的第一个应用程序来看到这个,然后你会得到一个AbandonedMutexException
(这意味着获得了Mutex)。使用以下内容重现,readline而不是按钮点击:
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
两次将使第一次“点击”(并在第二次崩溃)时起作用。您可以通过在创建锁时不获取锁定来解决此问题,从而解决此问题:
Mutex req_mutex = new Mutex(false, "req_mutex");
答案 2 :(得分:-1)
我想我找到了自己问题的答案......
显然,你做的WaitOne操作量确实很重要。 我获得了所有权(构造函数中的true参数)并在同一个线程中做了一个额外的WaitOne,假设它不会受到伤害。 现在为了释放互斥锁,我显然不得不两次调用ReleaseMutex。
我想我仍然可以这样做并在循环中调用ReleaseMutex直到抛出异常...