8

TCriticalSection方法とSynchronize操作方法を正しく理解したかどうかをここで確認したいと思います。

私の知る限り、現在実行中のスレッド(および他のスレッド)を一時停止SynchronizeするSendMessage(更新:または少なくとも古いVCLバージョンで使用)を使用しますPostMessage。関数(メインスレッドから)。ある意味でSendMessage、実行時にマルチスレッドを「停止」します。

しかし、私にはよくわかりませんTCriticalSection。たとえば、次のようなものを作成するとします。

// Global variables somewhere in my code any thread can access
boost::scoped_ptr<TCriticalSection> ProtectMyVarAndCallFnction(new TCriticalSection);
int MyVariable1;
void CallMyFunctionThatAlsoModifiesMoreStuff() { /* do even more here */ };


// Thread code within one of the threads
try {
    ProtectMyVarAndCallFnction->Acquire();
    MyVariable1++;
    CallMyFunctionThatAlsoModifiesMoreStuff();
    }
__finally {
    ProtectMyVarAndCallFnction->Release();
    }

さて、私の質問は、この場合、クリティカルセクションがMyVariable1を保護していること、および呼び出された関数が変更する可能性があることをどのように「知っている」かということです。

私がそれを正しく理解した場合(そうではありません)、MyVariable1を変更するか、この関数を呼び出す(または2つのいずれかを実行する)スレッドでAcquire()を正しく呼び出すのは私の責任です。言い換えれば、私TCriticalSectionはそれに論理的に割り当てたものを定義するユーザー定義のブロックと考えています。このブロックに書き込んだり、この関数を使用したりする可能性のあるすべてのスレッド内でAcquire()を呼び出す限り、変数のセットまたは特定の関数である可能性があります。たとえば、「DiskOp」はTCriticalSectionディスクに書き込む私の名前であり、「Internet」はTCriticalSectionインターネットからデータを取得する関数を呼び出す名前である可能性があります。正しくわかりましたか?

また、このコンテキスト内で、TCriticalSectionは常にグローバルな種類の変数である必要がありますか?

4

1 に答える 1

14

SendMessageは、現在実行中のスレッド(およびその他のスレッド)を一時停止します。

いいえ、それは正しくありません。SendMessage何も中断しません。SendMessageは、メッセージを同期的に配信するだけです。メッセージが配信されるまで、関数は戻りません。つまり、ターゲットウィンドウのウィンドウプロシージャが実行されました。また、ウィンドウprocは常にウィンドウを所有するスレッドで呼び出されるため、ウィンドウを所有するスレッドがウィンドウprocを実行する準備ができるまで待機するために、呼び出し元のスレッドをブロックする必要がある場合があります。プロセス内のすべてのスレッドを一時停止するわけではありません。

クリティカルセクションは、私が保護していることをどのようにして知るMyVariable1のですか?

そうではありません。保護が必要なすべての使用にMyVariable1保護が与えられていることを確認するのは完全にあなた次第です。クリティカルセクションは、ミューテックスの形式です。ミューテックスは、実行の1つのスレッドのみがいつでもミューテックスを保持できることを保証します。

Acquire()このブロックに書き込んだり、この関数を使用したりする可能性のあるすべてのスレッド内で呼び出すとき。

それも実際にはそうではありません。「すべてのスレッド内」は誤解です。「変数を使用するコードのすべてのセクションで」考える必要があります。

したがって、クリティカルセクションは常にグローバルな種類の変数である必要がありますか?

いいえ、クリティカルセクションはグローバル変数にすることができます。しかし、そうである必要はありません。

于 2012-12-03T13:27:29.950 に答える