--Multipart_Mon_Mar__1_19:47:55_1999-1 Content-Type: text/plain; charset=ISO-2022-JP Á°ÅĤǤ¹¡£ 1.3ÍѤËmonitor.rb¤ò ľ¤·¤Þ¤·¤¿¡¨Â ¤¹¤Ù¤Æ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤¬¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»ý¤Æ¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤ª ¤«¤²¤Ç¡¢Ruby¥ì¥Ù¥ë¤Ç¤Ïfinalizer¤ÎɬÍ×À¤Ï¤Ê¤¯¤Ê¤Ã¤¿¤È¹Í¤¨¤Æ ¤è¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¤Í¡£ Ruby¤Ç¤Ï¥Õ¥¡¥¤¥ë¤Ê¤É¤ÎÈó¥á¥â¥ê¥ê¥¹¤âC¥ì¥Ù¥ë¤Îfinalizer¤¬ ÌÌÅݤò¸«¤Æ¤¯¤ì¤Þ¤¹¤·¡£ ¤¢¤È¡¢instance_eval¤ò»È¤ï¤Ê¤¯¤Æ¤â¥«¥×¥»¥ë¤Ç¤¤ë¤è¤¦¤Ë¹© Éפ·¤Þ¤·¤¿¡£ Mixin¤ò¥¢¥¯¥»¥¹»ØÄê¤Ë»È¤¦Îã¤Ï¤¿¤Ö¤ó¤Ï¤¸¤á¤Æ¤À¤È»×¤¤¤Þ¤¹¡£ # ¤Ê¤¼¤Ê¤éprotected¤Ë¥Ð¥°¤¬¤¢¤Ã¤¿¤«¤é(^_^; --Multipart_Mon_Mar__1_19:47:55_1999-1 Content-Type: application/octet-stream Content-Disposition: attachment; filename="monitor.rb" Content-Transfer-Encoding: 7bit in monitor.rb Author: Shugo Maeda <shugo / netlab.co.jp> Version: 1.2 USAGE: foo oo.new foo.extend(MonitorMixin) cond oo.new_cond thread1: foo.synchronize { ... cond.wait_until { foo.done? } ... } thread2: foo.synchronize { foo.do_something cond.signal } ßÅ module MonitorMixin module Accessible protected attr_accessor :mon_owner, :mon_count attr_reader :mon_entering_queue, :mon_waiting_queue end module Initializable protected def mon_initialize @mon_owner il @mon_count @mon_entering_queue ] @mon_waiting_queue ] end end class ConditionVariable include Accessible def wait if @monitor.mon_owner ! hread.current raise ThreadError, "current thread not owner" end Thread.critical rue count monitor.mon_count @monitor.mon_count @monitor.mon_owner il if @monitor.mon_waiting_queue.empty? t monitor.mon_entering_queue.shift else t monitor.mon_waiting_queue.shift end t.wakeup if t @waiters.push(Thread.current) Thread.stop Thread.critical rue while @monitor.mon_owner ! il && @monitor.mon_owner ! hread.current @monitor.mon_waiting_queue.push(Thread.current) Thread.stop Thread.critical rue end @monitor.mon_owner hread.current @monitor.mon_count ount Thread.critical alse end def wait_while while yield wait end end def wait_until until yield wait end end def signal if @monitor.mon_owner ! hread.current raise ThreadError, "current thread not owner" end Thread.critical rue t waiters.shift t.wakeup if t Thread.critical alse Thread.pass end def broadcast if @monitor.mon_owner ! hread.current raise ThreadError, "current thread not owner" end Thread.critical rue for t in @waiters t.wakeup end @waiters.clear Thread.critical alse Thread.pass end def count_waiters return @waiters.length end private def initialize(monitor) @monitor onitor @waiters ] end end include Accessible include Initializable extend Initializable def self.extend_object(obj) super(obj) obj.mon_initialize end def try_mon_enter result alse Thread.critical rue if mon_owner.nil? self.mon_owner hread.current end if mon_owner Thread.current self.mon_count + result rue end Thread.critical alse return result end def mon_enter Thread.critical rue while mon_owner ! il && mon_owner ! hread.current mon_entering_queue.push(Thread.current) Thread.stop Thread.critical rue end self.mon_owner hread.current self.mon_count + Thread.critical alse end def mon_exit if mon_owner ! hread.current raise ThreadError, "current thread not owner" end Thread.critical rue self.mon_count - if mon_count 0 self.mon_owner il if mon_waiting_queue.empty? t on_entering_queue.shift else t on_waiting_queue.shift end end t.wakeup if t Thread.critical alse Thread.pass end def mon_synchronize mon_enter begin yield ensure mon_exit end end alias synchronize mon_synchronize def new_cond return ConditionVariable.new(self) end private def initialize(*args) super mon_initialize end end class Monitor include MonitorMixin alias try_enter try_mon_enter alias enter mon_enter alias exit mon_exit alias owner mon_owner end # Local variables: # mode: Ruby # tab-width: 8 # End: --Multipart_Mon_Mar__1_19:47:55_1999-1 Content-Type: text/plain; charset=ISO-2022-JP -- Á°ÅÄ ¨Â ÍõìôéðáòôßÍïîßÍáòß߱߱¹º´·ºµµß±¹¹¹±