ミューテックスは、マルチスレッドの問題を解決するために頻繁に使用されるプログラミング概念です。コミュニティへの私の質問:
ミューテックスとは何ですか?どのように使用しますか?
ミューテックスは、マルチスレッドの問題を解決するために頻繁に使用されるプログラミング概念です。コミュニティへの私の質問:
ミューテックスとは何ですか?どのように使用しますか?
回答:
仕事で大きな白熱した議論をしているとき、私はそのような時のために自分の机に置いてあるゴム鶏を使います。ニワトリを持っている人だけが話せる人です。ニワトリを持っていないと話せません。あなたが話したいのは、あなたが鶏肉が欲しいことを示し、それが手に入るまで待つだけです。話し終えたら、次の人に話しかけるモデレーターに鶏肉を戻すことができます。これにより、人々がお互いに話し合わないようにするだけでなく、独自の会話スペースを確保できます。
ChickenをMutexに、personをthreadに置き換えれば、基本的にはmutexの概念があります。
もちろん、ゴムのミューテックスなどはありません。ゴム鶏だけ。私の猫はかつてゴム製のネズミを飼っていましたが、彼らはそれを食べました。
もちろん、ラバーチキンを使用する前に、1つの部屋で実際に5人が必要かどうかを確認する必要があります。1人の部屋で1人ですべての作業を行うのは簡単ではありません。実際には、これは単に類推を拡張しているだけですが、あなたはアイデアを得ます。
Mutexは相互に排他的なフラグです。1つのスレッドを許可し、他のすべてのスレッドへのアクセスをブロックするコードセクションへのゲートキーパーとして機能します。これにより、制御されているコードが一度に1つのスレッドによってのみヒットされるようになります。完了したら、必ずミューテックスを解放してください。:)
相互排除。Wikipediaのエントリは次のとおりです。
http://en.wikipedia.org/wiki/Mutual_exclusion
mutexのポイントは、2つのスレッドを同期させることです。1つのリソースにアクセスしようとする2つのスレッドがある場合、一般的なパターンは、コードを入力する前に、最初のコードブロックがアクセスを試みてミューテックスを設定することです。2番目のコードブロックがアクセスを試みると、ミューテックスが設定されていることがわかり、コードの最初のブロックが完了するまで待機して(ミューテックスの設定を解除して)、続行します。
これがどのように達成されるかの具体的な詳細は、明らかにプログラミング言語によって大きく異なります。
マルチスレッドアプリケーションの場合、異なるスレッドが変数などの共通リソースを共有することがあります。多くの場合、この共有ソースには同時にアクセスできないため、一度に1つのスレッドだけがそのリソースを使用していることを確認するための構造が必要です。
この概念は「相互排除」(短いMutex)と呼ばれ、そのリソースなどを使用して、その領域内で1つのスレッドのみが許可されるようにする方法です。
それらの使用方法は言語固有ですが、多くの場合(常にではないにしても)オペレーティングシステムのミューテックスに基づいています。
関数型プログラミングなどのパラダイムにより、一部の言語ではこの構成が必要ありません(Haskell、MLが良い例です)。
C#では、使用される一般的なmutexはMonitorです。タイプは「System.Threading.Monitor」です。また、 ' lock(Object) 'ステートメントを介して暗黙的に使用することもできます。その使用例の1つは、シングルトンクラスを構築する場合です。
private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
lock(instanceLock)
{
if(instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
プライベートロックオブジェクトを使用するロックステートメントは、クリティカルセクションを作成します。前のスレッドが終了するまで待機するように各スレッドに要求します。最初のスレッドがセクションに入り、インスタンスを初期化します。2番目のスレッドは待機し、セクションに入り、初期化されたインスタンスを取得します。
静的メンバーのあらゆる種類の同期では、同様にlockステートメントを使用できます。
ミューテックスとは何ですか?
ミューテックス(実際、ミューテックスは相互排除の略です)は、スピンロックとも呼ばれ、重要な領域を保護して競合状態を防ぐために使用される最も簡単な同期ツールです。つまり、スレッドはクリティカルセクションに入る前にロックを取得する必要があります(クリティカルセクションでは、マルチスレッドは共通の変数を共有し、テーブルの更新、ファイルの書き込みなど)、クリティカルセクションを離れるとロックを解放します。
競合状態とは何ですか?
競合状態は、2つ以上のスレッドが共有データにアクセスでき、同時にそれを変更しようとすると発生します。スレッドスケジューリングアルゴリズムはいつでもスレッド間でスワップできるため、スレッドが共有データへのアクセスを試みる順序はわかりません。したがって、データの変更の結果はスレッドスケジューリングアルゴリズムに依存します。つまり、両方のスレッドがデータにアクセス/変更するために「競合」しています。
実際の例:
仕事で大きな白熱した議論をしているとき、私はそのような時のために自分の机に置いてあるゴム鶏を使います。ニワトリを持っている人だけが話せる人です。ニワトリを持っていないと話せません。あなたが話したいのは、あなたが鶏肉が欲しいことを示し、それが手に入るまで待つだけです。話し終えたら、次の人に話しかけるモデレーターに鶏肉を戻すことができます。これにより、人々がお互いに話し合わないようにするだけでなく、独自の会話スペースを確保できます。
ChickenをMutexに、personをthreadに置き換えれば、基本的にはmutexの概念があります。
@Xetius
C#での使用:
この例は、ローカルのMutexオブジェクトを使用して、保護されたリソースへのアクセスを同期する方法を示しています。ミューテックスの所有権を取得するまで、各呼び出しスレッドはブロックされるため、ReleaseMutexメソッドを呼び出してスレッドの所有権を解放する必要があります。
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
ここにいくつかの素晴らしい答えがあります、これはミューテックスが何であるかを説明するための別の素晴らしいアナロジーです:
鍵付きの単一トイレを検討してください。誰かが入るとき、彼らは鍵を取り、トイレは占有されます。他の誰かがトイレを使用する必要がある場合、彼らはキューで待つ必要があります。トイレ内の人物がされた場合に行う、彼らは、キュー内の次の人への鍵を渡します。分かりますよね?
ストーリーのトイレを共有リソースに、キーをミューテックスに変換します。トイレの鍵をとる(鍵をかける)ことで使用できます。キーがない(ロックがロックされている)場合は、待機する必要があります。キーが人から返却されたら(ロックを解除して)、自由に取得できます。
MUTEXを最初に理解するには、「競合状態」が何であるかを知る必要があり、それからMUTEXが必要な理由を理解するだけです。マルチスレッドプログラムがあり、2つのスレッドがあるとします。これで、ジョブキューにジョブが1つあります。最初のスレッドはジョブキューをチェックし、ジョブを見つけた後、実行を開始します。2番目のスレッドもジョブキューをチェックし、キューにジョブが1つあることを確認します。したがって、同じジョブポインターも割り当てられます。したがって、今何が起こっているのか、両方のスレッドが同じジョブを実行しています。これにより、セグメンテーション違反が発生します。これは競合状態の例です。
この問題の解決策はMUTEXです。MUTEXは、一度に1つのスレッドをロックする一種のロックです。別のスレッドがロックしたい場合、そのスレッドは単にブロックされます。
このPDFファイルのリンクのMUTEXトピックは、読む価値があります。
ミューテックス:ミューテックスの略ムート UAL のEx clusion。つまり、一度に1つのプロセス/スレッドがクリティカルセクションに入ることができます。複数のスレッド/プロセスが共有リソース(変数、共有メモリなど)を更新しようとする並行プログラミングでは、予期しない結果が生じる可能性があります。(結果は、どのスレッド/プロセスが最初のアクセスを取得するかによって異なります)。
このような予期しない結果を回避するには、同期メカニズムが必要です。これにより、一度に1つのスレッド/プロセスだけがそのようなリソースにアクセスできるようになります。
pthreadライブラリは、Mutexのサポートを提供します。
typedef union
{
struct __pthread_mutex_s
{
***int __lock;***
unsigned int __count;
int __owner;
#ifdef __x86_64__
unsigned int __nusers;
#endif
int __kind;
#ifdef __x86_64__
short __spins;
short __elision;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
# define __PTHREAD_SPINS 0, 0
#else
unsigned int __nusers;
__extension__ union
{
struct
{
short __espins;
short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS { 0, 0 }
} __elision_data;
__pthread_slist_t __list;
};
#endif
これは、mutexデータ型、つまりpthread_mutex_tの構造です。mutexがロックされると、__ lockは1に設定されます。ロック解除されると、__ lockは0に設定されます。
これにより、2つのプロセス/スレッドがクリティカルセクションに同時にアクセスできないようになります。