1. ホーム
  2. windows

[解決済み] ミューテックスとクリティカルセクションの違いは何ですか?

2022-05-16 13:52:22

質問

Linux、Windowsの観点から教えてください。

C#でプログラミングしているのですが、この2つの用語は違いがあるのでしょうか。例など、できる限り投稿してください...。

ありがとうございます。

どのように解決するのですか?

Windowsの場合、クリティカルセクションはミューテックスよりも軽量です。

ミューテックスはプロセス間で共有できますが、常にカーネルへのシステムコールが発生し、いくらかのオーバーヘッドがあります。

クリティカルセクションは、1 つのプロセス内でのみ使用できますが、競合の場合にのみカーネルモードに切り替わるという利点があります - 一般的なケースであるべき無競合取得は、信じられないほど高速です。 競合の場合、それらはカーネルに入り、何らかの同期プリミティブ (イベントやセマフォなど) で待機します。

私は、その 2 つの間の時間を比較する簡単なサンプル アプリケーションを書きました。 私のシステムでは、1,000,000 回の無制限の取得と解放の場合、ミューテックスは 1 秒以上かかります。 クリティカル セクションは、1,000,000 回の取得で ~50 ミリ秒かかります。

これはテスト コードです。これを実行すると、mutex が 1 番目または 2 番目の場合に同様の結果が得られたため、他の影響は見られません。

HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;

// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    EnterCriticalSection(&critSec);
    LeaveCriticalSection(&critSec);
}

QueryPerformanceCounter(&end);

int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);

QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    WaitForSingleObject(mutex, INFINITE);
    ReleaseMutex(mutex);
}

QueryPerformanceCounter(&end);

int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);