Win32APIにおけるマルチスレッドについて
Posted: 2012年2月11日(土) 16:17
とある本に掲載されているブロック崩しのサンプルプログラムについての質問です。
質問したいソース全文を貼り付けたいところですが、ソースには著作権がありますので、それはできそうもありません。
このような質問をするのは自分としても不本意なのですが、ある程度省略した形で疑問点のある部分のみを質問させて下さい。
ブロック崩しの内容は一般的なもので、プレイヤーが自分のバーを操作し、バーにボールがぶつかれば跳ね返り、上にあるブロックに当たればあたったブロックは消滅します。
疑問に思ったのはボールの動きについての処理をマルチスレッド化しているところです。
このボールの動きについて関するスレッドはWM_CREATEが生じた際にウィンドウプロシージャで作られ、その内容は次のようなものです。
(質問に直接関係ない型、引数、返り値等は省略しています。)
ThreadFunc() {
while(isRun) {
MoveBall();
InvalidateRect();
Sleep();
}
}
MoveBall()でボールの座標を表すグローバル変数をインクリメントあるいはデクリメントし、ボールの動きを表現するとともに、バー、壁、ブロックとの当たり判定を行っています。
InvalidateRect()でWM_PAINTが呼び出されると、バー、ボール、ブロック等の座標を示すグローバル変数にアクセスしそれぞれをウィンドウに描画します。
ここまでなら、なんら問題なくプログラムは動作すると思うのですが、問題はプレイヤーがバーを動かしたときです。
バーはマウスのあるポイントのx座標に移動するような使用です。具体的にはウィンドウプロシージャー内で次のような処理を行っています。
case WM_MOUSEMOVE:
barLocation.x=LOWORD(lParam);
InvalidateRect();
return 0;
barLocationはバーの座標を示すグローバル変数です。
MoveBall関数内においても、このグローバル変数barLocationにアクセスしてボールとの当り判定をしています。
この「ウィンドウプロシージャー内のbarLocationへのアクセス」と、「ThreadFunc関数内のbarLocationへのアクセス」がゲーム中に同時に起こるという可能性があると思うのですが、その場合データの整合性が失われてしまったりはしないのかな?と思いました。
ミューテックスなどを用いて、同期を行っている記述があれば納得もできるのですが、そういった記述はソース内に見当たりません。
自分のマルチスレッドのメモリアクセスについての認識が間違っているのでしょうか。
質問したいソース全文を貼り付けたいところですが、ソースには著作権がありますので、それはできそうもありません。
このような質問をするのは自分としても不本意なのですが、ある程度省略した形で疑問点のある部分のみを質問させて下さい。
ブロック崩しの内容は一般的なもので、プレイヤーが自分のバーを操作し、バーにボールがぶつかれば跳ね返り、上にあるブロックに当たればあたったブロックは消滅します。
疑問に思ったのはボールの動きについての処理をマルチスレッド化しているところです。
このボールの動きについて関するスレッドはWM_CREATEが生じた際にウィンドウプロシージャで作られ、その内容は次のようなものです。
(質問に直接関係ない型、引数、返り値等は省略しています。)
ThreadFunc() {
while(isRun) {
MoveBall();
InvalidateRect();
Sleep();
}
}
MoveBall()でボールの座標を表すグローバル変数をインクリメントあるいはデクリメントし、ボールの動きを表現するとともに、バー、壁、ブロックとの当たり判定を行っています。
InvalidateRect()でWM_PAINTが呼び出されると、バー、ボール、ブロック等の座標を示すグローバル変数にアクセスしそれぞれをウィンドウに描画します。
ここまでなら、なんら問題なくプログラムは動作すると思うのですが、問題はプレイヤーがバーを動かしたときです。
バーはマウスのあるポイントのx座標に移動するような使用です。具体的にはウィンドウプロシージャー内で次のような処理を行っています。
case WM_MOUSEMOVE:
barLocation.x=LOWORD(lParam);
InvalidateRect();
return 0;
barLocationはバーの座標を示すグローバル変数です。
MoveBall関数内においても、このグローバル変数barLocationにアクセスしてボールとの当り判定をしています。
この「ウィンドウプロシージャー内のbarLocationへのアクセス」と、「ThreadFunc関数内のbarLocationへのアクセス」がゲーム中に同時に起こるという可能性があると思うのですが、その場合データの整合性が失われてしまったりはしないのかな?と思いました。
ミューテックスなどを用いて、同期を行っている記述があれば納得もできるのですが、そういった記述はソース内に見当たりません。
自分のマルチスレッドのメモリアクセスについての認識が間違っているのでしょうか。