0

私はこれについてはっきりしていません、誰かが私のためにこれを確認できますか?

次の同期の問題があります。次のオブジェクトがあります。

A. Process 1, thread 1: Read & write access to the resource.
B. Process 1, thread 2: Read access to the resource.
C. Process 2, thread 3: Read access to the resource.

そして、アクセス条件は次のとおりです。

  1. B または C がオンの間は、A をブロックする必要があります。
  2. B は、A がオンの間だけブロックする必要があります。
  3. C は、A がオンの間のみブロックする必要があります。

そのため、2 つの名前付きミューテックスを使用することを考えました。

  • hMutex2 = 上記の条件 2 を満たすために使用されます。
  • hMutex3 = 上記の条件 3 を満たすために使用されます。
  • hStopEvent = 停止イベント (アプリが閉じている場合はスレッドを停止する必要があります)。

Aの場合:

HANDLE hHandles[3] = {hMutex2, hMutex3, hStopEvent};
DWORD dwRes = WaitForMultipleObjects(3, hHandles, FALSE, INFINITE);
if(dwRes == WAIT_OBJECT_0 + 2)
{
    //Quit now
    return;
}
else if(dwRes == WAIT_OBJECT_0 + 0 ||
    dwRes == WAIT_OBJECT_0 + 1)
{
    //Do reading & writing here
    ...

    //Release ownership
    ReleaseMutex(hMutex2);
    ReleaseMutex(hMutex3);
}
else
{
    //Error
}

B の場合:

DWORD dwRes = WaitForSingleObject(hMutex2, INFINITE);
if(dwRes == WAIT_OBJECT_0)
{
    //Do reading here
    ...

    //Release ownership
    ReleaseMutex(hMutex2);
}
else
{
    //Error
}

C の場合:

DWORD dwRes = WaitForSingleObject(hMutex3, INFINITE);
if(dwRes == WAIT_OBJECT_0)
{
    //Do reading here
    ...

    //Release ownership
    ReleaseMutex(hMutex3);
}
else
{
    //Error
}

誰かがこれを確認できますか:

  • 両方のミューテックスで WaitForMultipleObjects を呼び出すと、両方ともシグナル状態 (またはブロック) になりますか?
  • また、両方のミューテックスを解放する必要がありますか?
4

3 に答える 3

2

記述されているWaitForMultipleObjects呼び出し (3 番目のパラメーターの場合は FALSE) は、いずれかのミューテックスが通知されると返されます。これは、ライターとリーダーの 1 人の両方がリソースへの同時アクセスを取得できることを意味します。一方のリーダーがリソースにアクセスしている間に、もう一方のリーダーがそのミューテックスを解放している可能性があります。その時点で、ライターは解放されます。

したがって、そのように両方のミューテックスを使用するには、両方で待機する必要があります。ただし、その 3 番目のパラメーターを TRUE に設定することはできません。これは、そのスレッドを解放するために hStopEvent も通知する必要があることを意味するためです (これは明らかに望ましくありません)。

可能性の 1 つは、どのミューテックスが解放されたかを確認し、ライターに他のミューテックスも待機させてから続行することです。次に、タスクの完了後に両方を解放する必要があります。このタイプのソリューションの問題は、急いで複雑になり始める可能性があることです。ミューテックスを必要とするプロセスをさらに追加すると、注意を怠るとデッドロックが発生する可能性があります。リーダー/ライター タイプのロックを使用すると、処理がかなり簡素化されます。

編集これは実際には質問への回答の一部ではありませんが、関連するプロセスとリソースにアクセスする頻度、およびアクセス中にミューテックスを保持する時間に応じて、1 つのミューテックスを使用して単純化することができます。それをクリティカルセクションとして扱います...各プロセスは、リソースへのアクセスが必要なときにそれを取得します。もちろん、両方のリーダースレッド/プロセスが同時にアクセスできるわけではないため、許容される場合と許容されない場合があります。しかし、長期的に検証する方がはるかに簡単です。

于 2012-06-09T18:00:08.500 に答える
0

あなたが探しているのは、リーダーライターロックです。あなたのアルゴリズムには深刻な問題が 1 つあります。プロセス A の枯渇です。B と C が動作し続けてミューテックスを取得し続けると、A が入ることができなくなる可能性があります。

于 2012-06-09T18:00:53.680 に答える
0

実際のところ、私はそれに反対することができます。 パラメータを に設定するWaitForMultipleObjectsと、オブジェクトのいずれかが通知 された場合に返されます。ドキュメントは次のとおりです:) に設定すると、すべてのオブジェクトを待機します。waitAllFALSETRUE

ただし、ソリューションはうまくスケーリングしません。別の読み取りスレッドを追加すると、3番目のミューテックスで立ち往生します...

ただし、Writer/Readers の問題はこれまで何度も解決されてきました。既存の実装を調べてみませんか? 特に Windows 同期 API に慣れていない場合は、デバッグ時間を大幅に節約できます。(ティーザー: posix スレッドには readwritelock があり、boost にはshared_mutex.)

于 2012-06-09T17:59:55.023 に答える