.NETミューテックスは、プロセスの境界を越えて同期して使用すること

:.する転載NETミューテックスをプロセスの境界を越えて同期して使用すること

ミューテックスは排他制御のための略語は、訪問のためのコンピュータ上で同じリソース上で、同時に2つのスレッドを防ぐために、ミューテックスです。しかし、他の排他的、スレッド境界を越えることができミューテックスと比較。


何ミューテックスこと?

同期して他のスレッドと同じように、ミューテックスは、リソースへの排他的アクセスを提供します。ただし、システムリソースがミューテックスモニタ以上使用され、モニターが実現し、使用するC#のlockキーワードにロックすることです。

より強力なもたらし、より多くのシステムリソースを使用する - ミューテックスは、アプリケーションドメインの境界を越えてマーシャリングすることができ、スレッドは、プロセスの境界を越えて同期させることができます。

単純なミューテックス(クロスプロセスは、相互に排他的であることはできません)

最も簡単な方法は、直接、ミューテックスを使用することで  new 、その後、出て  Wait 待って、使用  ReleaseMutex リリースされます

1  プライベート 読み取り専用ミューテックス_mutex = 新しい新しいミューテックス();
 2  
。3  プライベート ボイドUseResource()
 4。 {
 5。     _mutex.WaitOne();
 6      
。7      // 短い待ち時間、私は公共資源の使用をふり。ここでは再入国の単一プロセス内のコードの一部はしませんです。
。8      のThread.sleep(500 );
 9  
10      _mutex.ReleaseMutex();
 11 }

パラメータがある  initiallyOwned として指定された場合、パラメータ  true スレッドが呼び出したときに、これはミューテックススレッド(待つ必要はありません)を表し作成するためのリソースを持っている  ReleaseMutex 他のスレッドが後に  WaitOne 有効になります。

実際に私たちは、この排他モードを記述するためにあまり行かないようにしかし、このアプローチは、プロセス間の同期を達成することはできません。

クロスプロセスミューテックスのミューテックスを作成します。

クロスプロセスミューテックスのミューテックスを作成するには、ミューテックスは、名前を付けなければなりません。

使用する  new Mutex(false, "Walterlv.Mutex") プロセス間の排他的アクセスリソースの名前付きミューテックスのロックを作成します。

オーバーロードされたコンストラクタを使用する場合は、最初のパラメータ  initiallyOwned 推奨値です  falseあなたは次のように指定されている場合ので、  true あなたは、このスレッドが最初に作成されたこの願うことを示すために、時間  Mutex のスレッドを、しかし、あなたはまっすぐなので  new 出て、あなたは基本的に、あなたが最初のものではありません最後に知ることができないので、  new アウト。

1  クラスプログラム
 2  {
 3。     静的 非同期タスクメイン(文字列[]引数)
 4。     {
 5。         VARのプログラム= 新しい新しいプログラム();
 6          ながら、真の7。         {
 8。             // 連続的にいくつかのリソースにアクセスしよう。このように、複数のプロセスが実行しているとき、あなたは、リソースへのアクセスの競合の高い確率をシミュレートすることができます。
9              program.UseResource();
 10              ザが待つ Task.Delay(50 );
 11          }
 12である     }
 13である 
14  
15      プライベート ボイドUseResource()
 16      {
 17。         VARミューテックス= 新しい新しいミューテックス(falseに" Walterlv.Mutex " );
 18である         mutex.WaitOne();
 19  
20である         。// 公共資源です。
21          // ここでも、2つの異なるプロセス、コードの一部が再入はありませんです。
22は、         VARのパス= @ " C:Users \ユーザー\ lvyi \デスクトップ\ walterlv.log " ;
 23は          Console.WriteLineを($ " [{DateTime.Now:Oは}]ファイル......書き始める" );
 24          File.AppendAllTextを(パス、$ " [{DateTime.Now:Oは}] ......ファイルの書き込みを開始します"、Encoding.UTF8);
 25          のThread.sleep(1000年);
 26である          File.AppendAllText(パス、$ " [} {DateTime.Now:O]が完了ファイルに書き込まれる。" 、Encoding.UTF8);
 27          Console.WriteLineを($ " [} {DateTime.Now:O]は、完全なファイルを書き込む。" );
 28  
29          mutex.ReleaseMutex();
 30      }
 31れます }

明らかに、我々は待機時間間隔のみ50ミリ秒のリソースを使用しますが、実際には待機時間が約1000ミリ秒で、このプログラムは二つのプロセスの影響の下で実行されていることに注意してください。プロセスオフ1つのターンの後、間隔は約50ミリ秒に復元します。

これは、ミューテックスがここで待っクロスプロセス相互排他における役割を果たして示しています。

二つのプロセスで上記のコードの結果を実行します

あなたはそれが最初にいくつかの特別な処理の外に作成されるかどうかを必要とする場合には、使用して  createdNew コンストラクタ引数。

1   プライベート ボイドUseResource()
 2      {
 3 -       VARミューテックス= 新しい新しいミューテックス(falseに" Walterlv.Mutex " );
 4。 ++       VARミューテックス= 新しい新しいミューテックス(trueに" Walterlv.Mutex "OUT  のvar createdNew);
 5。 
6。 -       mutex.WaitOne();
 7 ++       // ミューテックスはcreatedNewが真であることを、ここから出て作成された場合、最初の引数は実際に起こったので、我々は待つ必要がinitiallyOwnedについて説明します。
8++       // すでにミューテックスが既に存在する準備ができての説明がある場合createdNewがfalseの場合、逆に、我々はここで待つ必要があります。
9 ++       IF(!CreatedNew)
 10 ++       {
 11。 ++           mutex.WaitOne();
 12である ++       }
 13である         ......
 14          mutex.ReleaseMutex();
 15      }

例外を処理

ApplicationExceptionを

mutex.ReleaseMutex(); 現在のメソッドは、スレッドがこの関数を呼び出ししようとした場合にのみ、独自のスレッドの呼び出しすることができますが、ミューテックスを持っていなかった、スローされます  ApplicationException

どのようにそれを持っていますか?以前のコンストラクタで覚えている  initiallyOwned パラメータのですか?それはあなたが(実際には、我々はまた、必要とするこのmutexの所有者であるかどうかを指定し、ある  createdNew これを確認支援します)。

スレッドがミューテックスを持っていない場合は、我々は、使用する必要が  WaitOne ロックを待機するために取得します。

AbandonedMutexException

1  クラスプログラム
 2  {
 3      静的 非同期タスクメイン(文字列[]引数)
 。4      {
 5          // スレッドを開き、ミューテックスは、そのスレッドで得失われました。
6          VARスレッド= 新しい新しいスレッド(AbandonMutex);
 7          Thread.start();
 8  
9          //はそれ以外の場合は、ミューテックス回収システムとなり、プロセスは終了させてはいけません。
10          Console.Read();
 11      }
 12は、 
13である     プライベート 静的 ボイドAbandonMutex()
 14      {
 15          //は、ミューテックスを取得し、放出されなくなりました。
16          // ミューテックスが失われたように、このスレッドは、WAITONEの実行の終了時に終了しますので、。
17          VARミューテックス= 新しい新しいミューテックス(falseに" Walterlv.Mutex " );
 18である         mutex.WaitOne();
 19      }
 20 }

あなたはこのプロセスを実行すると、このプロセスを維持するために最初の時間が終了していないと変なものは何もありません上記のコード、。しかし、その後、あなたがプロセスの2番目のインスタンスを起動し、それが中になります  WaitOne が、例外を受け取ります- AbandonedMutexException

あなたがコードを使用することができないのであれば  try-finally それがロックを取得した後にリリースされることを確認するために、そして強く推奨  WaitOne 例外をキャッチするとき。ところで、思い出させるtry-finally 非同期コードを持つことができない、あなたが見ることができます:内部使用は、(AutoResetEventなど)UIスレッド同期ロックの参加はデッドロックにつながる可能性が待っています

言い換えれば、あなたは待つ必要があるとき、catch 異常に見えます。で  catch 終了した後、あなたは再びそれを使用する必要はありません  WaitOne 異常が発生した場合でも、あなたはまだロックを取得するので、待つことを。あなたが呼び出すことができることを  ReleaseMutex 確認するために、我々は先に述べたように、ロックを解除することができ、ロックを保持しているスレッドのみという。

1つの プライベート 静的 ボイドWAITONE()
 2  {
 3。     VARミューテックス= 新しい新しいミューテックス(falseに" Walterlv.Mutexは" );
 4      トライ
5      {
 6          mutex.WaitOne();
 7      }
 8。     キャッチ(AbandonedMutexException EX)
 9。     {
 10          Console.WriteLineを(" ロックされた放棄が見つかりました。" );
 11      }
 12は、      Console.WriteLineを(" ロック取得" );
 13 }

参考資料

ブログの掲示板

この記事では、頻繁に更新される、オリジナルをお読みください:  https://blog.walterlv.com/post/mutex-in-dotnet.html  、知識の古いエラー、より良い読書体験を誤解を避けるために。

おすすめ

転載: www.cnblogs.com/jshchg/p/11686572.html