我如何在C#中创建一个系统互斥 [英] How can I create a System Mutex in C#

查看:124
本文介绍了我如何在C#中创建一个系统互斥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能创建一个系统/多进程互斥,统筹使用相同的非托管资源的多个进程



背景:
我已经写了使用一个文件打印机,它只能由一个进程时使用的过程。如果我想使用它的计算机上运行多个程序,我需要一种方法来跨系统同步此。


解决方案
< BLOCKQUOTE>

您可以使用System.Threading.Mutex类,它有一个OpenExisting方法来打开一个名为系统互斥体。




这不回答这个问题:




我怎样才能创建一个系统/多进程互斥




要建立一个全系统的互斥体,调用System.Threading.Mutex构造函数的字符串作为参数。这也被称为一个命名为互斥。要查看它是否存在,我似乎无法找到一个更优美的方法不是试图捕捉:

  System.Threading.Mutex _mutey = NULL; 

{
_mutey = System.Threading.Mutex.OpenExisting(mutex_name);
//我们得到了Mutey,可​​以尝试获得由WaitOne的
_mutey.WaitOne锁();
}

{
//指定的互斥体不存在,我们应该创建
_mutey =新System.Threading.Mutex(mutex_name) ; //这些名称需要匹配。
}

现在,要成为一个优秀的程序员,你需要,当你结束程序,释放此互斥锁

  _mutey.ReleaseMutex(); 



或者,你可以让它在这种情况下它会被称为抛弃当你的线程退出,并允许另一个进程创建它。





作为一个方面说明的最后一句话描述了被放弃互斥体,当另一个线程获取该互斥锁,异常 System.Threading.AbandonedMutexException 将被抛出告诉他这是在被遗弃的状态中。





我不知道为什么我几年这种方式以前回答过的问题;有(并且是)一个构造函数重载是在检查现有的互斥体要好得多。事实上,我把代码似乎有一个竞争条件! (和可耻的是大家没有纠正我:-P!)



这里的比赛条件:想象两个进程,它们都试图在同一打开现有互斥时间,并且两个得到的代码的捕获部分。然后,其中一个进程创建互斥量,从此幸福地生活。其他进程,但是,尝试创建互斥体,但是这一次,它已经创造!这种检查/互斥的创造必须是原子的。



http://msdn.microsoft.com/en-us/library/bwe34f1k(v = VS.90)的.aspx



所以...

  VAR requestInitialOwnership = FALSE; 
布尔mutexWasCreated;
互斥M =新的Mutex(requestInitialOwnership,
MyMutex,出mutexWasCreated);



我觉得这里的技巧是,看来,你有你实际上并不有一个选项(看起来像一个设计缺陷给我)。有时你,如果你拥有互斥如果你发送真正 requestInitialOwnership 也说不清。如果你通过真正,看来,你调用创建互斥量,那么很明显你拥有它(通过文件证实)。如果你通过真正,您的电话没有创建互斥量,所有你知道的是,互斥锁已创建的,你不知道,如果其他进程或线程这或许创建互斥体目前拥有互斥锁。所以,你必须的WaitOne ,以确保你有它。但随后,有多少发布就做你做什么?如果一些其他进程拥有互斥体,当你得到它,那么只有你对的WaitOne 显式调用必须发布 D 。如果你对构造函数调用使你拥有互斥的,你叫的WaitOne 明确,你需要两个发布取值



我把这些话转换成代码:

  VAR requestInitialOwnership = TRUE; / *这似乎是一个错误* / 
布尔mutexWasCreated。
互斥M =新的Mutex(requestInitialOwnership,
MyMutex,出mutexWasCreated);

如果(mutexWasCreated!)
{
布尔calledWaitOne = FALSE;
如果/ *我不知道这样的* /
{
calledWaitOne = true的方法(iOwnMutex(米)!);
m.WaitOne();
}

doWorkWhileHoldingMutex();

m.Release();
如果(calledWaitOne)
{
m.Release();
}
}



由于我没有看到一个方法来测试是否您当前拥有互斥体,我会强烈建议你通过来构造,让你知道,你没有自己的互斥,你知道多少次叫发布


How can I create a system/multiprocess Mutex to co-ordinate multiple processes using the same unmanaged resource.

Background: I've written a procedure that uses a File printer, which can only be used by one process at a time. If I wanted to use it on multiple programs running on the computer, I'd need a way to synchronize this across the system.

解决方案

You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.

That doesn't answer the question:

How can I create a system/multiprocess Mutex

To create a system-wide mutex, call the System.Threading.Mutex constructor that takes a string as an argument. This is also known as a 'named' mutex. To see if it exists, I can't seem to find a more graceful method than try catch:

System.Threading.Mutex _mutey = null;
try
{
    _mutey = System.Threading.Mutex.OpenExisting("mutex_name");
    //we got Mutey and can try to obtain a lock by waitone
    _mutey.WaitOne();
}
catch 
{
    //the specified mutex doesn't exist, we should create it
    _mutey = new System.Threading.Mutex("mutex_name"); //these names need to match.
}

Now, to be a good programmer, you need to, when you end the program, release this mutex

_mutey.ReleaseMutex();

or, you can leave it in which case it will be called 'abandoned' when your thread exits, and will allow another process to create it.

[EDIT]

As a side note to the last sentence describing the mutex that is abandoned, when another thread acquires the mutex, the exception System.Threading.AbandonedMutexException will be thrown telling him it was found in the abandoned state.

[EDIT TWO]

I'm not sure why I answered the question that way years ago; there is (and was) a constructor overload that is much better at checking for an existing mutex. In fact, the code I gave seems to have a race condition! (And shame on you all for not correcting me! :-P )

Here's the race condition: Imagine two processes, they both try to open the existing mutex at the same time, and both get to the catch section of code. Then, one of the processes creates the mutex and lives happily ever after. The other process, however, tries to create the mutex, but this time it's already created! This checking/creating of a mutex needs to be atomic.

http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx

So...

var requestInitialOwnership = false;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership, 
         "MyMutex", out mutexWasCreated);

I think the trick here is that it appears that you have an option that you don't actually have (looks like a design flaw to me). You sometimes can't tell if you own the mutex if you send true for requestInitialOwnership. If you pass true and it appears that your call created the mutex, then obviously you own it (confirmed by documentation). If you pass true and your call did not create the mutex, all you know is that the mutex was already created, you don't know if some other process or thread which perhaps created the mutex currently owns the mutex. So, you have to WaitOne to make sure you have it. But then, how many Releases do you do? If some other process owned the mutex when you got it, then only your explicit call to WaitOne needs to be Released. If your call to the constructor caused you to own the mutex, and you called WaitOne explicitly, you'll need two Releases.

I'll put these words into code:

var requestInitialOwnership = true; /*This appears to be a mistake.*/
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership, 
         "MyMutex", out mutexWasCreated);

if ( !mutexWasCreated )
{
    bool calledWaitOne = false;
    if ( ! iOwnMutex(m) ) /*I don't know of a method like this*/
    {
        calledWaitOne = true;
        m.WaitOne();
    }

    doWorkWhileHoldingMutex();

    m.Release();
    if ( calledWaitOne )
    {
        m.Release();
    }
}

Since I don't see a way to test whether you currently own the mutex, I will strongly recommend that you pass false to the constructor so that you know that you don't own the mutex, and you know how many times to call Release.

这篇关于我如何在C#中创建一个系统互斥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆