C# 跨进程互斥实例
刚刚编写了一个简单的程序,必须一次处理一次,所以通过使用带有特定名称的键控C# 跨进程互斥实例,c#,.net,concurrency,mutex,C#,.net,Concurrency,Mutex,刚刚编写了一个简单的程序,必须一次处理一次,所以通过使用带有特定名称的键控互斥锁来实现这一点。 代码(简化)如下所示 static readonly string APP_NAME = "MutexSample"; static void Main(string[] args) { Mutex mutex; try { mutex = Mutex.OpenExisting(APP_NAME); // At this point, with
互斥锁来实现这一点。
代码(简化)如下所示
static readonly string APP_NAME = "MutexSample";
static void Main(string[] args)
{
Mutex mutex;
try
{
mutex = Mutex.OpenExisting(APP_NAME);
// At this point, with no exception,
// the Mutex is acquired, so there is another
// process running
// Environment.Exit(1); or something
}
catch (WaitHandleCannotBeOpenedException)
{
// If we could not acquire any mutex with
// our app name, let's create one
mutex = new Mutex(true, APP_NAME);
}
Console.ReadKey(); // Just for keeping the application up
// At some point, I just want to release
// the mutex
mutex.ReleaseMutex();
}
我的第一次尝试是实例化互斥体
,比如新互斥体(false,APP_NAME)
,但调用互斥体。ReleaseMutex()
引发异常
System.ApplicationException:“从未同步的代码块调用了对象同步方法。”
刚才注意到构造函数的第一个参数(initiallyOwned
)标记创建互斥体的当前线程是否拥有它,并且,毫不奇怪,线程不能释放不属于该线程的互斥体
因此,将此参数更改为true
修复了该问题,如上面的代码所示
我的问题是,这个参数的全部意义是什么?我的意思是,我什么时候需要创建一个我无法释放的互斥锁。
而且,如果我将参数initiallyOwned
设置为false
,那么谁真正拥有该互斥锁呢
谢谢
我什么时候需要创建一个我无法释放的互斥锁
这个问题实在太宽泛了。但一个不太宽泛的问题是:
当我创建互斥锁时,如何释放一个最初不属于我的互斥锁
答案很简单:创建互斥锁后,只需获取它。然后你可以释放它
如果我将参数initiallyOwned
设置为false,那么谁真正拥有互斥锁
这取决于Mutex
是否已经被其他线程或进程创建和获取。如果不是,那么就没有人拥有它,您的代码以后也可以获得它
当然,对于您正在处理的场景,您甚至不一定要获取互斥体。通常的方法是尝试使用创建Mutex
。如果您的代码实际创建了互斥体
,则将设置第三个参数。你永远不需要真正地获得它;您只是使用了这样一个事实,即操作系统将确保互斥体只创建一次
请注意,关于使用.NET编写单实例程序,已经有很多非常好的建议。我强烈建议您查看此处的信息:
没有人拥有互斥体,除非它是由某人通过调用其方法获得的。传递initiallyOwned:true
是试图立即获取新创建的互斥体,但这是有问题的。从:
您不应该使用此构造函数来请求初始所有权,除非您可以确定线程将创建命名互斥体
还有一种方法可以接受三个参数:
public Mutex (bool initiallyOwned, string name, out bool createdNew);
…但更简单的方法是,只创建互斥体,而不具有初始所有权,然后在您准备被阻止时获取它(以防它碰巧被其他人获取)
好吧,可能更聪明的方法是创建互斥体
,然后尝试WaitOne
并查看布尔
结果?@VRoxa yeap,调用WaitOne
,并为毫秒超时
参数设置零值当然是一个灵活的选择!只是为了完成。作为对文件引用的回应。。。在我在上面的第一个示例中创建互斥体时,我完全确定我可以创建命名的互斥体,不是吗?因此,这符合我的上下文。我认为您的代码在mutex=mutex.OpenExisting(APP\u NAME)
和mutex=new mutex(true,APP\u NAME)
行之间有一个竞争条件。另一个进程可以同时创建和获取互斥对象的所有权。这种可能性很小,但我肯定不会在生产环境中运行这段代码。
mutex = new Mutex(initiallyOwned: false, APP_NAME);
mutex.WaitOne(); // Potentially blocking