web-dev-qa-db-ja.com

C#でのMutexの使用

私はc#のスレッド化に少し慣れており、一般的に、私のプログラムではmutexを使用して、クリティカルセクション内のスレッドを1つだけ許可し、不明な理由でcwを実行しています私のクリティカルセクション内に複数のスレッドが入っていることがわかり、これが私のコードです:

Mutex m = new Mutex();
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();

私がここで間違いをしているかどうかを知りたいのですが、あなたの親切な助けに感謝します。

編集:

私のコードにはクラスが含まれているため、基本的には次のようになります。

public class test
{
    private mutex m;
    public test()
    {
         m = new mutex();
    }
    public func()
    {
         m.WaitOne();
         <C.S> // critical section here
         m.ReleaseMutex();
     }


    } 
31
Nadav Stern

ここでの問題は、すべての呼び出し元がdifferent mutexを使用していることです。通常はフィールドにすることで、ロックオブジェクトをsharedにする必要があります。たとえば、より単純なlockメタファーに切り替えます。

private readonly object syncLock = new object();
public void ThreadSafeMethod() {
    lock(syncLock) {
        /* critical code */
    }
}

またはミューテックスを使用します:

private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
    m.WaitOne();
    try {
        /* critical code */
    } finally {
        m.ReleaseMutex();
    }
}
56
Marc Gravell

このパターンはまったくロックしません。すべてのスレッドが新しいMutexオブジェクトを作成し、すぐにそのロックを所有します。他のスレッドは、新しいMutex自体を作成して使用します。

通常のlock()の使用を検討してください!

lock(_lockobject) {
   // do inside what needs to be done - executed on a single thread only
} 

_lockobjectは、クラス内の単純なプライベート変数です。

private object _lockobject; 

編集:コメンターに感謝します! lock(this)が危険な状況が存在します。だから私はそれを取り除いた。

5
user492238

各スレッドに独自のミューテックスを与えるようです。それは機能しません。

そして、ほとんどの場合、ミューテックスは過剰です。あなただけが必要です:

private static object syncLock = new object();  // just 1 instance

....

lock(syncLock)
{
    // critical section
}
5
Henk Holterman

実行アプリのインスタンスを識別するためのミューテックスの使用。

 using (Mutex mutex = new Mutex(true, "app name", out createdNew))
            {
                if (createdNew)//check app is already run
                {
                    KillOthers();
                    StartApp();
                }
                else
                {
                    MessageBox.Show("Another instance already running!");
                }
            }
1
Lakiya