From c063e618a9ce5fa2bf15c6ed6ab1bc14da97574f Mon Sep 17 00:00:00 2001 From: Sandor Szuecs Date: Fri, 3 Jun 2011 23:30:47 +0200 Subject: [PATCH] enhanced monitor doc Signed-off-by: Sandor Szuecs --- lib/monitor.rb | 165 ++++++++++++++++++++++++++++++++------------------------ 1 files changed, 94 insertions(+), 71 deletions(-) diff --git a/lib/monitor.rb b/lib/monitor.rb index e33dbe2..c3c5de1 100644 --- a/lib/monitor.rb +++ b/lib/monitor.rb @@ -1,81 +1,90 @@ -=begin - -= monitor.rb - -Copyright (C) 2001 Shugo Maeda - -This library is distributed under the terms of the Ruby license. -You can freely distribute/modify this library. - -== example - -This is a simple example. - - require 'monitor.rb' - - buf = [] - buf.extend(MonitorMixin) - empty_cond = buf.new_cond - - # consumer - Thread.start do - loop do - buf.synchronize do - empty_cond.wait_while { buf.empty? } - print buf.shift - end - end - end - - # producer - while line = ARGF.gets - buf.synchronize do - buf.push(line) - empty_cond.signal - end - end - -The consumer thread waits for the producer thread to push a line -to buf while buf.empty?, and the producer thread (main thread) -reads a line from ARGF and push it to buf, then call -empty_cond.signal. - -=end +# = monitor.rb +# +# Copyright (C) 2001 Shugo Maeda +# +# This library is distributed under the terms of the Ruby license. +# You can freely distribute/modify this library. +# require 'thread' -# -# Adds monitor functionality to an arbitrary object by mixing the module with -# +include+. For example: -# -# require 'monitor' -# -# buf = [] -# buf.extend(MonitorMixin) -# empty_cond = buf.new_cond -# -# # consumer -# Thread.start do -# loop do -# buf.synchronize do -# empty_cond.wait_while { buf.empty? } -# print buf.shift -# end -# end -# end -# -# # producer -# while line = ARGF.gets -# buf.synchronize do -# buf.push(line) -# empty_cond.signal -# end -# end -# +# +# In concurrent programming, a monitor is an object or module intended +# to be used safely by more than one thread. The defining +# characteristic of a monitor is that its methods are executed with +# mutual exclusion. That is, at each point in time, at most one thread +# may be executing any of its methods. This mutual exclusion greatly +# simplifies reasoning about the implementation of monitors compared +# to reasoning about parallel code that updates a data structure. Read +# more about the general principle at +# Wikimedia[https://secure.wikimedia.org/wikipedia/en/wiki/Monitor_%28synchronization%29]. +# +# == Examples +# +# === Simple object.extend +# +# require 'monitor.rb' +# +# buf = [] +# buf.extend(MonitorMixin) +# empty_cond = buf.new_cond +# +# # consumer +# Thread.start do +# loop do +# buf.synchronize do +# empty_cond.wait_while { buf.empty? } +# print buf.shift +# end +# end +# end +# +# # producer +# while line = ARGF.gets +# buf.synchronize do +# buf.push(line) +# empty_cond.signal +# end +# end +# # The consumer thread waits for the producer thread to push a line # to buf while buf.empty?, and the producer thread (main thread) # reads a line from ARGF and push it to buf, then call # empty_cond.signal. +# +# === Simple Class include +# +# require 'monitor' +# +# class SynchronizedArray < Array +# +# include MonitorMixin +# +# def initialize(*args) +# super(*args) +# end +# +# alias :old_shift :shift +# alias :old_unshift :unshift +# +# def shift(n=1) +# self.synchronize do +# self.old_shift(n) +# end +# end +# +# def unshift(item) +# self.synchronize do +# self.old_unshift(item) +# end +# end +# +# # other methods ... +# end +# +# +SynchronizedArray+ implements an +Array+ with synchronized access +# to items. This +Class+ is implemented as subclass of +Array+ mixin +# the +MonitorMixin+ module. # module MonitorMixin # @@ -215,11 +224,15 @@ module MonitorMixin private + # Use Object#extend(MonitorMixin) or + # Object#include instead of this constructor. Have look at + # the examples above to understand how to use this module. def initialize(*args) super mon_initialize end + # Initialize the MonitorMixin within an Object. def mon_initialize @mon_owner = nil @mon_count = 0 @@ -245,6 +258,16 @@ module MonitorMixin end end +# Create a +Monitor+ class if you want to have a lock object for +# blocks with mutual exclusion. +# +# require 'monitor' +# +# lock = Monitor.new +# lock.synchronize do +# # exclusive access +# end +# class Monitor include MonitorMixin alias try_enter try_mon_enter -- 1.7.5.3