マルチスレッド: 同期クラスの使い分け
MFC に用意されているマルチスレッド クラスは 2 種類に分類できます。同期オブジェクト (CSyncObject、CSemaphore、CMutex、CCriticalSection、CEvent) と同期アクセス オブジェクト (CMultiLock、CSingleLock) です。
同期クラスは、リソースへのアクセスを制御してリソースの整合性を保証するときに使います。 同期アクセス クラスは、これらの被制御リソースにアクセスするときに使います。 このトピックでは、各クラスの使い分けについて説明します。
使用する同期クラスは、以下の質問に対する回答によって決まります。
アプリケーションは、なんらかの要因が発生するまで、リソースにアクセスできないですか (通信ポートからデータを受信しないと、データをファイルに書き込めない場合など)。
これに該当する場合は、CEvent を使用します。
同じアプリケーション内の複数のスレッドから同時にリソースにアクセスできますか (アプリケーションで 5 つまでのウィンドウのビューに同じドキュメントを表示できる場合など)。
これに該当する場合は、CSemaphore を使用します。
複数のアプリケーションでリソースを使用できますか (リソースが DLL 内にある場合など)。
これに該当する場合は、CMutex を使用します。
いずれにも該当しない場合は、CCriticalSection を使います。
CSyncObject は直接使わないでください。 このクラスは、ほかの 4 つの同期クラスの基本クラスです。
例 1 : 3 種類の同期クラスを使う方法
たとえば、アカウントのリンク リストを保持するアプリケーションの場合を考えます。 このアプリケーションでは 3 つまでのアカウントを個別のウィンドウで調べることができます。ただし、一度に更新できるアカウントは 1 つだけとします。 更新されたデータはネットワークを通じてデータ アーカイブに送られます。
このアプリケーションでは、3 種類の同期クラスをすべて使います。 同時に調べることができるアカウントは 3 つまでなので、CSemaphore を使って 3 つのビュー オブジェクトだけにアクセスを制限します。 4 番目のアカウントを表示しようとすると、アプリケーションは最初の 3 つのウィンドウのいずれかが閉じるのを待つか、失敗します。 アカウントを更新する場合、アプリケーションは CCriticalSection を使って一度に 1 つのアカウントだけを更新します。 更新に成功すると、CEvent を発行し、このイベントの発行を待っていたスレッドを解放します。 新しいデータは、このスレッドからデータ アーカイブに送られます。
例 2 : 同期アクセス クラスを使う方法
同期アクセス クラスを使い分けるのはさらに簡単です。 アプリケーションが単一の被制御リソースにアクセスするときは、CSingleLock を使います。 複数の被制御リソースのいずれかにアクセスするときは、CMultiLock を使います。 例 1 では、一度に 1 つのリソースが必要なので、CSingleLock を使用します。
同期クラスの使用方法については、「マルチスレッド : 同期クラスの使用法」を参照してください。 同期については、Windows SDK の「Synchronization」を参照してください。 MFC によるマルチスレッドのサポートについては、「C++ と MFC を使用するマルチスレッド」を参照してください。