- ベストアンサー
マルチタスキング?について教えてください。
素人です。 小規模なコンソールアプリとか作たりした事は有るのですが、ふと気になった事が有ります。 ゲーム等のように音楽鳴らしたりしながら別の処理をしたりと言うようなプログラムってどのようにすると実現出来るのでしょうか? マルチタスキング?マルチスレッド?どっちか解りませんがどのようにして実現できるかご教授ください。 あと、ソースを複数に分けて書く(*.cppを複数に分ける)にはどのようにしたら良いでしょうか? VC++2008使ってます。よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>ゲーム等のように音楽鳴らしたりしながら別の処理をしたりと言うようなプログ>ラムってどのようにすると実現出来るのでしょうか? 基本的には 音楽を鳴らすスレッドを1つつくり実行させます。 OSはCPUに時間ごとに仕事(タスク)を与えます。 複数のCPUがあれば同時に複数の仕事を実行できます (マルチタスク) 1つしかCPUがなくても、OSがCPUに仕事を割り振る単位が 非常に短いので 人間からは同時に仕事が行われているようにみえます これもマルチタスクと呼ばれます 仕事 = プログラムとは限りません 仕事とは"開始" から "終了"まで一本の糸で結ばれているものです。 これをスレッドと言います。 OSはスレッド単位で仕事を割り振るのです。 ゲームの場合も "音楽"をちょっと演奏、その他をちょっと、また音楽... これを最後まで行う 一本の糸 として作ることも可能です。 この場合、1本のプログラムにスレッド1個だけなので "シングル・スレッド"と呼ばれます しかし、音楽、その他をまとめて一本にするより 音楽で一本 その他で一本 合計2本のスレッドで1つのゲームを構成する と考えたほうが わかりやすいです この場合 1本のプログラムに複数スレッドがあるので "マルチスレッド" となります。 当然ですがプログラムには最低1つのスレッドがあります。 >あと、ソースを複数に分けて書く(*.cppを複数に分ける)にはどのようにしたら良>いでしょうか? Visual Sudioでの操作方法は他の人に譲るとして、 プログラムを作る立場で考えます。 複数のソースに分けるのは(基本的には)良いことです。 しかし、やたらに長いソースが見にくいように 意味もなく分けたソースも分かりにくいものです。 ソースを分ける際には そのソースが一体何を目的としているのか、 いったん立ち止まって考えてください。 ある程度の”まとまり”で他の部分と区別させる。 中身は(ある程度)ブラックボックス状態で使える単位で切り出します。 C++の場合、1つのスースに1つのクラスがわかりやすいです。 (そのためVSのウィザード等もそうなっています) しかし、必ずしもこだわる必要はありません。 ある"機能"を実現するために1つのソースを使うわけですが、 それを実現するためにちょっとしたクラスを使いたい時があります。 例えば ゲームのデータ(Save/Loadするもの)を管理する目的で CGameDataクラスを作ったとします データをファイルへ記録する際に (MFCなどの)ライブラリクラスをカスタマイズしたいとします。 CGameFileとします。 それ自体はCGameDataとは別のクラスになるるわけです。 もちろんCGameFileをCGameDataと別にソース(h,cpp)を起こしても構いません。 (ウィザードでは当然そうなります) しかし、CGameFileのコードが比較的短く、かつCGameData以外からは まったく使われない場合、 CGameDataのソース(cpp)にCGameFileの宣言/実装もすべて含める こともよくあります。 一見汚いのですが、 こうすることで CGameFileの存在をCGameData以外に対し隠すことができます。 CGameFileのインターフェースを変更しても CGameData以外に何の影響も与えないことを保証できます。 独立させた場合 いろんなところでつかえてしまうので CGameFileのインターフェースを変えたら CGameData以外に影響を与えないかチェックする必要があります。 こういった意味でも 特に複雑なプログラムでは ソースを分ける・分けないは慎重に考えるべきだと思います。
その他の回答 (4)
- BLK314
- ベストアンサー率55% (84/152)
>仕組み自体は簡易的なCPU設計したりしたこと有るので解るのですが、 >実際Cで実装するとなると一本のソースに >別々の処理を互い違いに書く他無いのか?と思いまして。 必ずしもそうは言えないと思います。 スレッドを1本のモジュールととらえてもよいと考えます。 たとえば、音楽演奏を別スレッドにし、別モジュールにすることも可能です。 音楽演奏開始・中断・再開・終了その他のAPIを定義します。 実際にはスレッドハンドルやイベントハンドル等で実装することになりますが、 詳細は音楽モジュールのソースに完全に隠ぺいします。 こうすれは 音楽演奏のソースは音楽演奏制御のみ、"その他の処理"は考えない "その他の処理"は自分のこと + 音楽制御との通信 となります さらに、 ”その他の処理"から"ゲーム全体の制御"を切り離し "音楽"と並列に行う処理(キャラクター制御等)をスレッド・モジュール化する こともできます。 "ゲーム全体の制御"はいわゆる”スレッド0(メインスレッド)"で行わせます。 例えば”ボス・キャラ登場"などに合わせて音楽を切り替えることを考えます。 この場合、キャラクタ制御と音楽演奏スレッドが同期していないと 音楽演奏の開始タイミングが早すぎたり遅すぎたりして違和感があるわけです。 それをキャラ制御と音楽制御の通信で実装することも可能なわけですが、 そうすると見通しが悪くなってしまします。 そうではなくて、メインスレッドがそれぞれのAPIを呼び出すことにすれば 見通しは良くなると考えられます。 いかがでしょうか?
お礼
大変遅くなってしまいました。 せっかく回答して頂いたのに申し訳ございません。 各タスクのような感じですね。 プログラム内で独立したプログラムを時分割してプロセッサで処理する訳ですか。 なるほど。
- zwi
- ベストアンサー率56% (730/1282)
>仕組み自体は簡易的なCPU設計したりしたこと有るので解るのですが、実際Cで実装するとなると一本のソースに別々の処理を互い違いに書く他無いのか?と思いまして。 まぁ、CPUのハードの割り込み処理をアセンブラで書く場合にもそうですが、1本のソースファイルにメインスレッドとサブスレッドの処理を書く必要はありませんし、スレッドから関数(アセンブラならサブルーチン)を呼び出しても問題ありません。 で、互い違いに書く他無いのかって観点からすると「その通りです」。なのでスレッド間でお互いのタイミングを計る場合はソースコードの見渡しは悪いです。 で、タイミングやデータを受け渡す場合は、スレッド間の同期(データの受け渡しやタイミングの制御)が必要になります。 http://ina-infotech.com/VisualCPP/Thread/Thread.html http://wisdom.sakura.ne.jp/system/winapi/win32/win145.html ちなみにマルチタスク/スレッドは、CPUのタイマ割り込みの仕組みで実現されています。
お礼
回答有難うございます。 >で、互い違いに書く他無いのかって観点からすると「その通りです」。なのでスレッド間でお互いのタイミングを計る場合はソースコードの見渡しは悪いです。 なるほど。
- zwi
- ベストアンサー率56% (730/1282)
C言語のソース分割について補足しておきます。 とりあえず、コンパイルとリンクについて理解を深めてください。 http://www.grapecity.com/japan/powernews/column/clang/003/default.htm でC言語の関数のソースファイル分割の方法です。 http://www.geocities.jp/ky_webid/c/032.html 最後にVC+2008での新規のソースやヘッダの追加方法ですが。 プロジェクト > 新しい項目の追加 で.cppや.hを追加できます。
- zwi
- ベストアンサー率56% (730/1282)
>マルチタスキング?マルチスレッド? マルチタスクはOSの機能ですね。複数のアプリが同時に動いてみえますよね?それがマルチタスクです。 マルチスレッドで、サウンド制御やらファイルロードをするのが定番です。 とりあえず説明は簡単に出来ないの下記サイトを見てもらうとして http://wisdom.sakura.ne.jp/system/winapi/win32/win143.html で、ここを見ても良く分らない場合は、とりあえずOSやCPUの知識不足です。 本を紹介しますので、立ち読みするか購入を検討してください。 難易度は次の順です。 APIで学ぶWindows徹底理解 > Windowsはなぜ動くのか ≒ CPUのきもち http://www.amazon.co.jp/CPU%E3%81%AE%E3%81%8D%E3%82%82%E3%81%A1%E2%80%95IA%E2%80%9032%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%E3%81%A8WindowsXP%E3%81%AE%E4%B8%8D%E6%80%9D%E8%AD%B0%E3%81%AA%E9%96%A2%E4%BF%82-%E5%94%AF%E9%87%8E-%E5%8F%B8/dp/4839917280 http://www.amazon.co.jp/Windows%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E5%A4%A9%E9%87%8E-%E5%8F%B8/dp/4822281493/ref=pd_sim_b_2 http://software.nikkeibp.co.jp/software/backno/04apimook2.html >ソースを複数に分けて書く(*.cppを複数に分ける)にはどのようにしたら良いでしょうか? クラスの追加で新規にクラスを追加すれば、新しいクラスは別ソースファイルになります。 それともC言語の話ですか?
お礼
回答有難うございます。 紹介して頂いたHP読んでみます。 >それともC言語の話ですか? Cの話ですね。
お礼
回答有難うございます。 >1つしかCPUがなくても、OSがCPUに仕事を割り振る単位が 非常に短いので 人間からは同時に仕事が行われているようにみえます これもマルチタスクと呼ばれます 丁寧な説明有難うございます。 仕組み自体は簡易的なCPU設計したりしたこと有るので解るのですが、実際Cで実装するとなると一本のソースに別々の処理を互い違いに書く他無いのか?と思いまして。 >複数のソースに分けるのは(基本的には)良いことです。 >しかし、やたらに長いソースが見にくいように >意味もなく分けたソースも分かりにくいものです。 ごもっともです。 しかしまだそのような議論を出来るほどの力量が有りません。 ですのでせめて方法を知って、失敗して学ぼうという感じですね。