21

ネット上のあちこちで何度も読んだことがあるので、ミューテックスはクリティカルセクション/セマフォ/insert-your-preferred-synchronisation-method-hereよりも低速です。しかし、私はこの主張を裏付ける論文や研究などを見たことがありません。

それで、このアイデアはどこから来たのですか?それは神話ですか、それとも現実ですか?ミューテックスは本当に遅いですか?

4

5 に答える 5

19

JimBeveridgeとRobertWienerによる「win32のマルチスレッドアプリケーション」という本の中で、次のように述べています。カーネルを含む」

そして、ここのmsdnには、「クリティカルセクションオブジェクトは、相互排除同期のためのわずかに高速で効率的なメカニズムを提供します」と書かれています。

于 2009-11-03T11:07:02.847 に答える
17

なぜ違うのかという要点に、どの答えも当てはまるとは思いません。

ミューテックスはオペレーティングシステムレベルです。名前付きミューテックスが存在し、オペレーティングシステムの任意のプロセスからアクセスできます(ACLがすべてのプロセスからのアクセスを許可している場合)。

クリティカルセクションは、カーネルモードへのシステムコールを必要としないため高速ですが、プロセス内でのみ機能し、クリティカルセクションを使用して複数のプロセスをロックすることはできません。したがって、達成しようとしていることとソフトウェア設計がどのように見えるかに応じて、その作業に最も適したツールを選択する必要があります。

さらに、セマフォは数が多いため、ミューテックス/クリティカルセクションとは別のものであることを指摘しておきます。セマフォを使用して、リソースへの複数の同時アクセスを制御できます。ミューテックス/クリティカルセクションは、アクセスされているか、アクセスされていないかのどちらかです。

于 2009-11-03T11:34:18.703 に答える
5

CRITICAL_SECTION は、スピン カウントが制限されたスピンロックとして実装されます。これについては、 MSDN InitializeCriticalSectionAndSpinCountを参照してください。

スピン カウントが「経過」すると、クリティカル セクションはセマフォ (またはそれが実装されているカーネル ロック) をロックします。

したがって、コードでは次のように機能します(実際には機能していません。単なる例です):

CRITICAL_SECTION s;

void EnterCriticalSection( CRITICAL_SECTION* s )
{
    int spin_count = s.max_count;
    while( --spin_count >= 0 )
    {
        if( InterlockedExchange( &s->Locked, 1 ) == 1 )
        {
           // we own the lock now
           s->OwningThread = GetCurrentThread();
           return;
        }
    }
    // lock the mutex and wait for an unlock
    WaitForSingleObject( &s->KernelLock, INFINITE );
}

したがって、クリティカル セクションが非常に短時間しか保持されず、入力スレッドがごくわずかな「スピン」(サイクル) しか待機しない場合、クリティカル セクションは非常に効率的です。しかし、そうでない場合、クリティカル セクションは何もせずに多くのサイクルを浪費し、カーネル同期オブジェクトにフォールバックします。

したがって、トレードオフは次のとおりです。

Mutex : 取得/解放は遅いが、長い「ロックされた領域」の無駄なサイクルがない

CRITICAL_SECTION : 所有されていない「領域」の取得/解放は高速ですが、所有されているセクションのサイクルは浪費されます。

于 2009-11-03T11:52:53.760 に答える
3

はい、クリティカルセクションの方が効率的です。非常に良い説明については、「Windowsでの並行プログラミング」を入手してください。

一言で言えば、ミューテックスはカーネルオブジェクトであるため、「無料」であっても、ミューテックスを取得すると常にコンテキストスイッチがあります。その場合、クリティカルセクションはコンテキストスイッチなしで取得でき、(マルチコア/プロセッサマシンでは)高価なコンテキストスイッチを防ぐためにブロックされている場合は、数サイクルもスピンします。

于 2009-11-03T11:13:36.320 に答える
2

ミューテックス (少なくとも Windows では) は、スレッドに加えて異なるプロセス間の同期を可能にします。これは、これを確実にするために余分な作業を行う必要があることを意味します。また、ブライアンが指摘したように、ミューテックスを使用するには「カーネル」モードへの切り替えも必要であり、これにより別の速度低下が発生します (このプロセス間同期にはカーネルが必要であると私は信じています。つまり、推測しますが、バックアップするものは何もありません私はそれについて)。

編集:ここでプロセス間同期への明示的な参照を見つけることができます。このトピックの詳細については、Interprocess Synchronizationをご覧ください。

于 2009-11-03T11:17:47.347 に答える