From: Kazuhiro NISHIYAMA Date: 2003-09-18T23:42:08+09:00 Subject: [ruby-dev:21401] Re: Per-Thread stdout が欲しい 西山和広です。 In <20030918112530.71CA.TIETEW-ML-RUBY-DEV@tietew.net> On Thu, 18 Sep 2003 11:39:18 +0900 Tietew wrote: > 表題の通りなんですが,現状プロセスグローバルな $std{in,out,err} > の,スレッドローカルな奴が欲しいのです。背景としては,同じプロセ > ス上で互いに無関係な ruby スクリプトがスレッドを分けた上で同時に > 実行され得るアプリ(Becky! のプラグインなんですが)を開発してい > て,$stdout を切り替えたときにそれが(一時的でも)全体に波及する > のを防ぎたいという意図です。 グローバル変数なのでtrace_varを使えばrubyレベルで なんとか出来そうです。 class PerThreadIO < Delegator def initialize(symbol) @default_io = eval(symbol.to_s) super(@default_io) @symbol = symbol trace_var(symbol) {|newval| Thread.current[symbol] = newval eval %Q{#{symbol} = self} } end def __getobj__ Thread.current[@symbol] || @default_io end end if __FILE__ == $0 PerThreadStdin = PerThreadIO.new(:$stdin) PerThreadStdout = PerThreadIO.new(:$stdout) PerThreadStderr = PerThreadIO.new(:$stderr) require 'stringio' th1 = Thread.start do str = "" strio = StringIO.new(str) $stdout = strio $stdout.puts "th1: a" sleep $stdout.puts "th1: b" str end $stdout.puts "main thread: a" th1.wakeup $stdout.puts "main thread: b" $stderr.puts th1.value end -- |ZnZ(ゼット エヌ ゼット) |西山和広(Kazuhiro NISHIYAMA) # http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/ruexli/ruexli/lib/perthreadio.rb