2008年10月25日土曜日

マルチスレッド

スレッド(Thread, ThreadPool)って、どういう時に使うんですか?

新人SEに聞かれたことがある。良い質問。技術を学ぶには「何でこんなものが必要なんだろう?」という疑問が不可欠。

さて、業務系ソフト開発でスレッド(非同期処理)を使う場面といえば…適当な例が見当たらない。ぱっと浮かぶのは「大量の帳票出力処理をスレッド化しておくと、出力中もオペレーション出来る」なんて事くらい。
あとはタイマー処理かな。スレッドでカウントしておいて、一定時間毎に画面のリフレッシュとか。あまり良い例では無いね。

こういう時は実例で説明するのが一番。下記は実例を基にした話。


■ 要件と問題

製造業の「発注先選定システム 企業評価編」といったところ。

原材料の仕入先や加工等の外注先(見積依頼先)を絞り込むシステム。
諸条件から検索を行うが、この時、結果リストは評価点(X)の高いものが上位に表示される。X は品質評価(A),納期評価(B),価格評価(C)の立方根とする。A,B,C は過去数年間のデータを、X は各評価の結果を基に日次算出する。

要件を確認したとき「各評価の算出式だけ分かってしまえば楽勝!」と、簡単に考えていた。

ところが実際にテストアプリを作って分かったのが「各評価算出には非常に時間が掛かる」ということ。各1時間かかるとして大体3時間。夜間バッチとは言え、販売管理の集計等が終わってから評価処理を開始すると…始業に間に合わない。

DBバックアップの時間も関係してくるし、どうしよう。週次にしようか?


■ スレッド利用

とにかくロジックの見直し。個々の評価算出については後にして、取りあえず全体最適化に注力。あれ? 各評価って、互いに関連していないね。非同期で算出しても良いのか。むむっ!


それから、ハードウェア仕様を確認すると、評価算出に使うアプリケーションサーバの CPU は Xeon(Irwindale)で Hyper-Threading 対応。「せっかくのHT。活かさないと勿体無い」ということで、設計を見直し。

A,B,C 個々の評価算出メソッドをスレッドプールで実行し、結果を DataTable に書き込む形に変更。
処理が全部終わった時点で、この DataTable の企業コードをループ(評価点の計算)し、結果全体を一度に書き戻すことにした。

この結果、評価算出処理は本当に 1/3 の時間で完了。始業に間に合う。

これを応用すれば各評価算出をWebサービス経由で別サーバに任せ、結果セットを受け取って処理する様なことも可能。10倍の規模なら、そうするかも。100倍規模なら企業コード単位で評価算出サーバに渡す形として、1評価につき複数台をロード・バランシング! ふぅー…カッコイイ


何の話だっけ? マルチスレッド?
新人SEにはこの例を解説し「複数の結果セットで集計を行う場合、過程は非同期で算出して良く、スレッド利用が適している」と回答したかな。
 

3 件のコメント:

匿名 さんのコメント...

先生! スレッドといえばやっぱり、ネットワーク関係ではないでしょうか。
ぜひ、ネットワーク関係の例を出して説明してください。

koucho さんのコメント...

んんん?

ネットワーク関係とは、Webサーバのワーカースレッドとか、そういうのでしょうか?

匿名 さんのコメント...

そんなところです。
Web に限らずサーバー側のプログラミングで複数のクライアントからの接続を受け付けている時など、スレッドを使うことで、一つのクライアントとの通信が終わらなくても次のクライアントを受け付けられるようにしますよね。

またクライアント側でも、サーバーからの応答を待たずに例えばマウス操作を受け付けたりするためにスレッドを使います。