#pragma twice

KAB-studio > プログラミング > #pragma twice > 300 Version 14.33 マルチスレッドのまとめ

#pragma twice 300 Version 14.33 マルチスレッドのまとめ

前のページへ 表紙・目次へ 次のページへ

 Version 14.33
マルチスレッドのまとめ

というわけで、マルチスレッド編は以上で終了
今回も長かったね……
半年以上掛かったからね……というわけで、振り返ってみましょう
 Version 14.01 ( No.268 ) が最初だね
初めは、スレッドじゃなくプロセスを例に取って説明しました
そういえばそれってなんで?
こういう理由、かな

・同期オブジェクトはスレッド関係なく使えるため。
・スレッドの同期処理はプログラムが複雑になってわかりにくいため。
ファイルに対する複数プロセスのアクセスの方が、スレッドを使った
 プログラムよりも使用頻度が高いため。

確かに同期オブジェクトはマルチスレッドのためのものなんだけど、その
マルチスレッドを最初に持ってくるとどうしても複雑になっちゃうんだよ

あのプログラムじゃね……
それに、同期ってマルチスレッドを使わなくても必要な知識だから、それ
をまず先にってこと
そこで、まず Version 14.03 ( No.270 ) でファイルのロック、んで
Version 14.04 ( No.271 ) から Version 14.13 ( No.280 ) まで、
同期オブジェクトの説明ってわけね
同期オブジェクトだけまとめると、こんな感じ

・ミューテックス
 ひとつのシグナルを持ち、普通にオン/オフするだけ。
 監視者が複数の場合、オンになった時に通知されるのは
 一番先に監視した監視者に対して。
 Version 14.05 ( No.272 )
 Version 14.06 ( No.273 )

・セマフォ
 複数のシグナルを持ち、その個数分だけ同時にオンになる。
 全てのシグナルがオンの場合、新たな監視者へはオフを返し、
 他の監視者が監視を終了して空きができるとオンに切り替わり
 監視者へと通知される。これにより処理数を調節できる。
 Version 14.08 ( No.275 )
 Version 14.09 ( No.276 )

・タイマー
 一定時間毎にオンになるシグナルを持つ。
 先に監視した監視者から順番に通知される。
 Version 14.10 ( No.277 )
 Version 14.11 ( No.278 )

・イベント
 好きなときにオン/オフを切り替えられるシグナルを持つ。
 オンに切り替わったとき、監視者全員に通知される。
 Version 14.12 ( No.279 )
 Version 14.13 ( No.280 )

・クリティカルセクション
 他の同期オブジェクトと異なり、プログラムに排他処理を掛ける。
 Version 14.18 ( No.285 )
 Version 14.19 ( No.286 )

クリティカルセクションだけあとなのは、クリティカルセクションが
マルチスレッドでしか使えないからだよね
そう。他の4つはプロセス間での同期に使えるんだけど、
クリティカルセクションだけはひとつのプロセスの中でしか機能しないから
そういえば、この5つの同期オブジェクトって、どれが一番使えるの? 
マルチスレッドの例の時って結局使わなかったけど
マルチスレッドの時に使わなかったのは、簡単な例だったからっていうの
もあるんだけど、できれば同期オブジェクトを使わないくらいシンプルな方
がマルチスレッドではいいかな、と思うんだけど
それって投げっぱなしで複雑なことしないのがいいって言ってたやつ?
そう、マルチスレッドはちょっとしたことでも複雑になりやすいからね。
でも、同期オブジェクトの使いどころは結構あるよ
そなの?
特にセマフォは使いどころ多いかも。インターネットの複数のページに同
時にアクセスさせる時とかに、数を制限しつつ処理できるから
バトンの数、っていうのをうまく使うわけね
まぁそれでも、マルチスレッドの場合、変数を共有できるからそれで十分
間に合うっていうのもあるし、 WaitForSingleObject() で待機するとそれ
だけでメッセージループ止まっちゃうっていうのもあるし
あ、そういえばそうじゃん! そういうときってどうするの?
別スレッドにします
……
というふうにどんどん複雑になっていくわけ
だからシンプルにってわけねー
そういうこと。まぁ実際には、ウィンドウ処理を行いさえしなければ、ど
んどん使えるんだけどね
どゆこと?
それは次回の話。話を戻して、同期オブジェクトは変数の共有と、普通の
タイマーでなんとかなることが多いから、マルチスレッドの時には使わなく
ても済むかな
クリティカルセクションは?
使いようによっては、ってところかな。スレッドを複数起動して、それぞ
れのスレッドが同時にアクセスする変数が複数ある場合とかは必要かも
変数が複数ある場合?
変数がひとつの場合は同期を考える必要ないけど、変数Aと変数Bから値
を取得して変数Cに書き込む場合
変数Aを取得した後に他のスレッドが変数Bを書き換えたらまずい、って
ことね
そういうこと。そういう場合にはクリティカルセクションでロックを掛け
るのがいいかな。まぁ使わなくてもできちゃうけど
できるの?
変数もうひとつ用意して、それをフラグにすれば
結局、変数は同期オブジェクトの代わりになっちゃうわけね
同期オブジェクトを使うメリットは、同期オブジェクトにしか使えないか
ら間違って使う事がない、とか、 WaitForSingleObject() とかの待機系関
数を使える、とかかな
待機系関数使うとウィンドウ固まる、って考えるとホントにメリット少な
いよね
だね。同期オブジェクトも結構クセのある仕様だから、無理に使わなくて
もいいかもね。と、話を戻して、同期オブジェクトの説明の間に
デッドロックの説明をしました
 Version 14.07 ( No.274 ) だね。あと Version 14.21 ( No.288 ) と
Version 14.22 ( No.289 ) でもやったよね
クリティカルセクションを使った例だね。結局は、デッドロックが起きる
ようなプログラムを作らないように、〈投げっぱなし〉にするのが重要か

投げっぱなしでシンプルに、ってわけね
同期オブジェクトの説明のあと、本編の中心、マルチスレッドの説明をし
ました
 Version 14.14 ( No.281 ) からの、ね
別の流れとして関数を呼び出す、基本的にはそれだけのこと
逆に言うと、複雑なことするな、ってことね
そういうこと。プログラムが複雑になってもいいことは何もありません
でも、複雑にしちゃいそう……
そのためにも〈投げっぱなし〉を忘れずに
2度目のデッドロックの説明の後、 Version 14.23 ( No.290 ) から 
Version 14.25 ( No.292 ) までメッセージループの解説だったよね
この〈なんでアプリが固まるのか〉を理解してないと、スレッドを使う必
要性が感じないからね
ちょっとした処理でもウィンドウが固まるって考えると、なんかなんでも
かんでも別スレッドで処理したくなるけど
それは難しいところだね。現実的に、全ての処理をマルチスレッド化する
のは不可能です
そんなことしたらきりないもんね
切り分けるとしたら、次のような場合は〈処理を別スレッドで行い、途中
でキャンセルできるようにする〉のがいいかな

・特定のファイル内の全文に対する処理。
・特定のフォルダ内のファイル全部への処理。
・ネットワーク処理

ファイルとネットワーク?
特にファイルは重要。ファイルは、ひとつのファイルでも数 Gbyte とか
あり得るわけだから
そりゃあり得るだろうけど……
考えてるよりもずっと多いよ、そういうこと。たとえば普通にアプリが
ファイルを読み込む場合でも、間違って大きなムービーを開いたりしたら
げ……それは使う人が悪いんじゃないの?
まぁそうとも言えるかな。そういうことをマニュアルに書いておけばそれ
で済むことになるから
う……でもやっぱ、途中でキャンセルできた方がいいよね
まぁね。他にも、途中でうまくいかなくなることが多いネットワーク関係
も、かな
ネットワーク関係まだ教わってません!
ネットワークは、範囲が広すぎるので #pragma twice では取り上げない
予定
え”、そうなの……?
その話はとりあえず置いといて。あとで説明するから
りょーかい。マルチスレッドの最後は、 Version 14.26 ( No.293 ) の応
用編だよね。ここは複雑だった……
処理が色々な所にまたがってるからね
検索するのと、キャンセルダイアログと、メインのダイアログと。こうい
うのってもっとうまくやる方法ってないの?
あるよ。今回の方法がちょっときれいじゃないのは、マルチスレッドの方
をメインに見ていたから。プログラム全体で考えればもう少しスマートな感
じになるかな
それって、プログラム全体を見直すってこと?
そういうこと。元々の構造が、 VC++ の AppWizard で作ったものそのまま
だったでしょ
そりゃそうだけど、それに手を加えるのは……
というわけで、次の次の章では、プログラム全体について考えてみま
す!
おお、って次の次?
そう、次の次。次回、 Version 15 は、非常に深い話をします
深い……話?
そう、ビルドとかコンパイルとかそういった部分の話
へ? 前にちょっとやったけど……
 Version 6.01 ( No.101 ) とかだね。 Version 15 では、コンパイルや 
Exe の仕組み、 DLL の説明をします
……なんかそれって、マニアック過ぎない?
ううん、多分一番重要なところ
え、そうなの?
火美ちゃんとしては、ビルドしたら Exe ができるからいい、って考える
かもしれないけど
うん
それは他のプログラミング言語の話
へ?
 Exe がどういうものなのか、どうやって DLL と結びついているのか、そ
ういうコアな場所に一番近いのが VC++ で、それを知っていて当然と思われ
るのが VC++ プログラマーです
知ってて当然?
というか、他の言語のプログラマーの場合、そういうのは知らなくていい
って教わるから……でも、本当の意味でのプログラマーは、知っている必要
のある部分。そして、そこに一番近いのが……
 VC++ ってことなんだ……
 Version 15 ではそういったある意味最も基本的なことを教えます。そし
て、 Version 16 ではプログラム全体の話。主にクラスを使った、設計まで
踏み込んだ説明をします
なんかいきなりレベル上がってきてるような……
そんなことないよ
へ?
気付いてないかもしれないけど、火美ちゃんにはとても多くの事を教えて
あるから。残りの2章でそれを全部継なげれば、きっと全体が見えてくる

そ、そうなんだ……へ? 残り2章って言った?

/*
    Preview Next Story!
*/
残り2章……
長かったような短かったような
長かった!! 絶対! てかあと2章で終わるの!?
……終わらないかも
うわっ……
それよりも次回の話。次回はコンパイルについて説明します
って、それやったじゃない
というわけで次回
< Version 15.01 ソースファイルのコンパイル >
につづく!
前にやったけど、それをもっともっと深く説明します
それやるから時間掛かるのよー!!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。