Tbpgr Blog

Recruiting Operations tbpgr(てぃーびー) のブログ

マルチスレッドデザインパターン | Thread-Per-Messageパターン

概要

Thread-Per-Messageパターン

詳細

一つのメッセージに対して1つのスレッドを割り当てるパターン。
依頼者が作業者に処理を依頼すると、該当作業は別スレッドで実行され
待機する必要がないため依頼者は即別の作業を行うことが出来ます。
これにより、プログラムの即時性が上がります。

注意点

・応答性の向上と、スレッドの起動オーバーヘッドとのバランスで採用有無を決める
・戻り値が不要な際のみ利用可能
・処理が変わっても問題ない場合に利用可能

構成

・Client:依頼者
・Host:依頼者から依頼を受け、スレッドを起動する
・Helper:スレッド内での実際の処理

サンプル

仕様

ある英文のテキストファイルから1回のリクエストにつき1個の単語をランダムで抽出し、標準出力します。
※動作確認用のテキストは英語版WikipediaのDesignPatternページの一部を抽出したもの

構成

・Client:RandomWordClient
・Host:RandomWordHost
・Helper:RandomWordHelper
・テキストファイル:text.txt

ソースコード
# encoding: utf-8
require "pp"
require "thread"

class RandomWordClient
  def request
    puts "start client"
    host = RandomWordHost.new
    (1..10).each do |i|
      host.request i
    end
    puts "end   client"
  end
end

class RandomWordHost
  def initialize
    @helper = RandomWordHelper.new
  end

  def request(no)
    Thread.start {puts "#{no}:#{@helper.get_random_word}"}
  end
end

class RandomWordHelper
  TEXT = "./text.txt"

  def get_random_word
    contents = File.open(TEXT) {|f|f.read}
    ret = contents.split(/[\s|,|\.]/).sample
    return ret.empty? ? get_random_word : ret
  end
end

client = RandomWordClient.new
client.request
sleep(1)
出力例

メイン処理が終了後に結果が出力されていること(待機なしでメイン処理が進んでいる)、
各スレッドの終了順がバラバラであること
などが下記結果から確認出来る。
1回目

start client
end   client
1:Wiley
5:Schmidt
2:0-321-20068-3
6:ISBN
8:practically
7:books
9:in
3:ISBN
4:Hans
10:System

2回目

1:Although
2:)
8:ISBN
5:In
9:Building
7:Sierra
10:Kathy
3:Ward
6:Frank;
4:(1996)