- blogs:
- cles::blog
2010/10/18

RubyのWin32OLEは現状でマルチスレッド対応ではないらしい

先日書いたエントリのサンプルには問題があって、スレッドは切り替わるもののWin32OLEの呼び出し部分でブロックしてしまうので、Ruby 1.9にしても本質的にはうまく実行できません。前回は待ち時間が短かかったのと、タイムスタンプを出力していなかったのでスケジューリングがめちゃくちゃなことに気づいていませんでした。
また、Ruby 1.9.2のWIN32OLEの欄にも以下の注意書きがあったのですが見落としていました。
マルチスレッドでの利用制限
注)以下の記述はWIN32OLEの将来のバージョンの仕様を規定するものではありません。
WIN32OLEはシングルスレッドモードでCOMとインターフェイスします。このため、ruby 1.9以降のRubyのThreadとネイティブスレッドが1対1で対応する実行環境ではスレッドをまたがる呼び出しはエラーとなります。
ということで、現在のところWin32OLE内でブロックするプログラムをマルチスレッドでうまく動かす方法はないようです。Win32OLEマルチスレッド対応という話もあるようなので、もしかしたらもう少しで解決されるのかも知れないので、期待して待ちたいと思います。
† テストコード
oletest.rb
start = Time.now
require 'win32ole'
require 'thread'
module MSMQ; end
WIN32OLE::const_load(WIN32OLE.new('MSMQ.MSMQQueueInfo'), MSMQ)
QUEUE_NAME = 'test'
MAX_THREAD = 3
@threads = ThreadGroup.new
@active = true
Signal.trap(:INT){
puts "SIGINT trapped\n"
@active = false
@threads.list.each{ |thread| thread.run }
}
MAX_THREAD.times do |n|
t = Thread.new do
mqi = WIN32OLE.new('MSMQ.MSMQQueueInfo')
mqi.PathName = '.\private$\\' + QUEUE_NAME
q = mqi.Open(MSMQ::MQ_RECEIVE_ACCESS,MSMQ::MQ_DENY_NONE)
while @active
msg = q.Receive("ReceiveTimeout" => 5000)
# msg = q.Receive("ReceiveTimeout" => 1); sleep 5
puts "#{Time.now.to_s}:#{n}:Label:#{msg.Label}, Body:#{msg.Body}, Priority:#{msg.Priority}\n" if msg
puts "#{Time.now.to_s}:#{n}:nil massage\n" unless msg
end
puts "#{Time.now.to_s}:#{n}:terminated!\n" unless msg
end
@threads.add(t)
end
puts "waiting...\n"
@threads.list.each{ |thread| thread.join }
puts "#{Time.now - start}sec.\n"
† 検証結果
上記のコードをそのまま実行した結果は下記の通り。
各スレッドの結果が5秒ごとに得られているのかと思ったのですが、まったくのデタラメでした。
この現象はブロックする時間が増えたり、スレッドが増えるほどどんどん酷くなります。
C:\tmp>ruby oletest.rb
waiting...
2010-10-18 22:23:34 +0900:0:nil massage
2010-10-18 22:23:39 +0900:2:nil massage
2010-10-18 22:23:44 +0900:1:nil massage
2010-10-18 22:23:49 +0900:0:nil massage
2010-10-18 22:23:54 +0900:2:nil massage
2010-10-18 22:23:59 +0900:1:nil massage
2010-10-18 22:24:04 +0900:0:nil massage
2010-10-18 22:24:10 +0900:2:nil massage
2010-10-18 22:24:15 +0900:1:nil massage
2010-10-18 22:24:20 +0900:0:nil massage
2010-10-18 22:24:25 +0900:2:nil massage
2010-10-18 22:24:30 +0900:1:nil massage
2010-10-18 22:24:35 +0900:0:nil massage
2010-10-18 22:24:40 +0900:2:nil massage
2010-10-18 22:24:45 +0900:1:nil massage
2010-10-18 22:24:50 +0900:0:nil massage
2010-10-18 22:24:55 +0900:2:nil massage
2010-10-18 22:25:00 +0900:1:nil massage
2010-10-18 22:25:05 +0900:0:nil massage
SIGINT trapped
2010-10-18 22:25:10 +0900:2:nil massage
2010-10-18 22:25:20 +0900:2:terminated!
2010-10-18 22:25:15 +0900:1:nil massage
2010-10-18 22:25:20 +0900:1:terminated!
2010-10-18 22:25:20 +0900:0:nil massage
2010-10-18 22:25:20 +0900:0:terminated!
コメントのアウトされている部分を有効化し、その上の行をコメント化してsleepをRuby側で行うようにすると、各スレッドでちゃんと5秒ごとに結果が取れるようになります。自分的にはこちらが意図した動きですが、これはRuby1.8でも実現できるのではないかと思います。
C:\tmp>ruby oletest.rb
waiting...
2010-10-18 22:27:37 +0900:2:nil massage
2010-10-18 22:27:37 +0900:1:nil massage
2010-10-18 22:27:37 +0900:0:nil massage
2010-10-18 22:27:42 +0900:2:nil massage
2010-10-18 22:27:42 +0900:1:nil massage
2010-10-18 22:27:42 +0900:0:nil massage
2010-10-18 22:27:47 +0900:2:nil massage
2010-10-18 22:27:47 +0900:1:nil massage
2010-10-18 22:27:47 +0900:0:nil massage
2010-10-18 22:27:52 +0900:2:nil massage
2010-10-18 22:27:52 +0900:1:nil massage
2010-10-18 22:27:52 +0900:0:nil massage
2010-10-18 22:27:57 +0900:2:nil massage
2010-10-18 22:27:57 +0900:1:nil massage
2010-10-18 22:27:57 +0900:0:nil massage
SIGINT trapped
2010-10-18 22:27:58 +0900:0:nil massage
2010-10-18 22:27:58 +0900:0:terminated!
2010-10-18 22:27:58 +0900:1:nil massage
2010-10-18 22:27:58 +0900:1:terminated!
2010-10-18 22:27:58 +0900:2:nil massage
2010-10-18 22:27:58 +0900:2:terminated!
26.520046sec.
トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3856
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
サイト内検索
検索ワードランキング
へぇが多いエントリ
閲覧数が多いエントリ
1 . アーロンチェアのポスチャーフィットを修理(112029)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110663)
3 . 年次の人間ドックへ(110291)
4 . 2023 年分の確定申告完了!(1つめ)(109829)
5 . 三菱鉛筆がラミーを買収(109737)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110663)
3 . 年次の人間ドックへ(110291)
4 . 2023 年分の確定申告完了!(1つめ)(109829)
5 . 三菱鉛筆がラミーを買収(109737)
cles::blogについて
Referrers