テクニカルレシピ(Visual C++のレシピ)

Home>>Visual C++>>フリーズ防止 LastUpdate:2009-01-21

マルチスレッド

描画処理、データ処理の負荷が高い場合、
プログラムがクリックなどの外部入力に応答できなくなる場合があります。
(プログラムがフリーズしてしまいます。)

この問題を防ぐにはマルチスレッドの技術を使います。
描画処理とデータ処理のスレッドを分けるのです。
(ソースファイルはサンプルコードのtips4.zipにまとめてあります。)

マルチスレッドといっても全く難しくありません。
Visual C++のAPIを使うと、独立したワークスレッド(データ処理スレッド)を簡単に作れます。

必要な知識は2つです。
@イベントハンドラからAfxBeginThreadでワークスレッドを起動
Aワークスレッド用関数はUINT型を返し、引数はLPVOID型

AfxBeginThreadはおまじないと思ってください。
スレッドを起動するためのAPIです。
このAfxBeginThreadにはスレッドで起動したい関数を引数として渡します。
この引数の形式がUINT、LPVOIDと決まっているのです。

詳しくは具体的なコードを見てください。
前項までに動的レイアウト再描画処理ちらつき防止を加えたダメアプリをさらに改良してみます。

まずイベントハンドラ関数では変数を初期化し(@)、
AfxBeginThreadを使ってワークスレッドを起動します(A)。
このとき引数としてWorkThreadという関数とthisポインタを渡します。
WorkThreadはスレッドにしたい関数名で、
thisポインタはスレッド内から変数にアクセスするために使います。

ワークスレッド関数の具体的な関数を下に示します。
繰り返しですが形式は決まっています。
返値はUINT、引数はLPVOIDで作ってください。

スレッド内ではまず引数のキャストを行いメンバへのアクセスを可能にします(@)。
(先ほどのthisポインタをCtips4Dlg型にしてこの関数内で使えるようにしています。)

あとはこの引数(pDlg)を使ってデータ処理を行うだけです(A)。
メンバ変数はpDlgからアクセスできるので、
データの設定も通常の関数と変わりません。
1回のデータ処理毎にInvalidate(再描画命令)を読んでいます(B)。

マルチスレッドに必要な処理は上の処理だけです。
これでデータ処理と描画処理が独立したスレッドとなり、
プログラム実行中にフリーズしません。

再生回数が多い場合でも途中でStopボタンで停止させることが出来ます。

ちらつき防止:前項<< ページの先頭に戻る >>次項:私の参考書