マルチスレッド

Download Report

Transcript マルチスレッド

プロジェクト演習Ⅳ
インタラクティブゲーム制作
プログラミング4
2011/11/8
マルチスレッドと
真・ストリーミング再生
今日の内容
• マルチスレッドプログラム
– 1つのプログラム内で2カ所以上
「同時に実行」できる程度の能力
– 重い処理で画面や入力受付を止めたくない
時や、設計次第では高速化にも寄与
• 音楽再生の改善
– ロード中に音が止まらなくなるよ!
– やったね!
マルチスレッドとは
• 1つのプログラムの中で複数の関数が
同時に(並列して)動かせる技術のこと
– 今まで皆さんが書いていたプログラムは
「実行している箇所」は1カ所だけだった
• シングルスレッド
• マルチスレッドの導入により、メイン
ループを回しつつ、他のスレッドで重い
処理をさせることができるようになる
例えば
// いつものメインループ
while(true) {
// 画面描画や入力受付
update();
// BGM再生
play();
// この中で重たいロードが発生
loadHeavy();
// ここで数秒間処理が止まると当然update()側に処理が渡らない!
// 当然play()も呼ばれないので曲再生が止まる
}
何故音楽が止まるのか?
• OpenALでは「キュー
バッファ」と呼ばれ
る方式によってスト
リーミング再生して
いる
• play()の中で更新を
しているので、長時
間play()が呼ばれな
いとバッファを使い
切って止まる
数秒分の
波形データ
数秒分の
波形データ
再
生
時
間
こんなことが出来るようになる!
// こっちはメインループ
while(true) {
// 画面描画や入力受付
update();
// BGM再生
if(再生開始?) playStart();
// 後は投げっぱなしでおk
// この中で重たいロードが発生
if(読み込む?) loadStart();
if(読み込み中?) {
今何%くらいかを取得;
画面に表示して待たせる;
}
}
// 別スレッドを作成
void playMain()
{
while(true) {
play();
if(ほげほげ)break;
}
}
// それとは別に作ってもいい
void loadMain()
{
loadHeavy();
}
メリット・デメリット
• 重い処理をメイン
ループから外して処
理の高速化、効率化
が見込める
– バックグラウンド読み
込み、ローディングの
進捗表示、ネットワー
ク処理、BGMのスト
リーミング再生など夢
は広がるばかり
• データのアクセスに
制約が付く
• バグった時の対応難
度が跳ね上がる
• 苦労して別スレッド
にしてもその割には
リターンが少ない、
あるいは悪化するこ
ともある
今回のサンプルは
Windows限定コード
• boostというライブラリを使うと、
機種依存せずにスレッド処理が可能
• ただし、ライブラリのサイズが膨大か
つ、コンパイル速度が低下するなどの影
響も
• boostはおすすめしたいのですが、
今回は学習の利便性をとって
Windowsネイティブの実装にしました
使い方
• Javaライクにしてあります
– ThreadBaseクラスを継承して
MyThreadクラスを作る
– main()をオーバーライドして、
別スレッドで行う処理を実装する
– MyThreadオブジェクトを作り、
start()をコール
• main()を直接コールしてはだめ
– 止める時はend()をコール
別スレッドで操作している
データの参照
• 必ず受け渡し用のメンバ関数を作る
• そのメンバ関数内でlock()~unlock()を忘
れずにコールする
– lock()して
– 返値用の変数にデータをコピーしたりして
– unlock()する
• これを怠ると、データの読み書きが
かちあってSUGOIことになる
コンストラクタとデストラクタを
使ったテクニック
• lock()~unlock()で
わざわざ関数全体を
囲うのが面倒
• あるスコープに入っ
た時と出た時に行う
処理を楽に書きたい
• じゃあ→こんなん
どうでしょう?
class fkut_CriticalSection {
public:
fkut_CriticalSection(void)
{
fkut_ThreadBase::lock();
};
~fkut_CriticalSection()
{
fkut_ThreadBase::unlock();
};
};
// このクラスの変数をスコープ内に
宣言するだけでおkになる
// 型名が長いのが嫌ならtypedefを
typedef fkut_CriticalSection fkut_CS
Segaの偉い人曰く…
• プログラムは基本シングルスレッドで書
くモノである
• マルチスレッドプログラムで起きる挙動
は人間の理解を超えている
• 本当にどうしても必要な場合に、最低限
の利用に留めることをおすすめする
• だ、そうです
アドバイス
• よく分からなかった
ら使わなくてもいい
• 無理して使ってもド
ツボにはまるだけな
ので
• これが出来ないと作
れない「遊び」とい
うのは存在しない
– スマートにはなるけど
• 使いどころは
– BGM再生用に1本
– データロード用に1本
• データロードしつつ
ゲーム本体を動かすの
は厳禁
• 進捗表示や待機アニメ
程度にする
• ぐらいにしておこう