1#!/usr/local/bin/ruby 2# SimpleTupleSpace 3# Copyright (c) 1999-2000 Masatoshi SEKI 4# You can redistribute it and/or modify it under the same terms as Ruby. 5 6require 'thread' 7 8class SimpleTupleSpace 9 def initialize 10 @hash = {} 11 @waiting = {} 12 @hash.taint 13 @waiting.taint 14 self.taint 15 end 16 17 def out(key, obj) 18 Thread.critical = true 19 @hash[key] ||= [] 20 @waiting[key] ||= [] 21 @hash[key].push obj 22 begin 23 t = @waiting[key].shift 24 @waiting.delete(key) if @waiting[key].length == 0 25 t.wakeup if t 26 rescue ThreadError 27 retry 28 ensure 29 Thread.critical = false 30 end 31 end 32 33 def in(key) 34 Thread.critical = true 35 @hash[key] ||= [] 36 @waiting[key] ||= [] 37 begin 38 loop do 39 if @hash[key].length == 0 40 @waiting[key].push Thread.current 41 Thread.stop 42 else 43 return @hash[key].shift 44 end 45 end 46 ensure 47 @hash.delete(key) if @hash[key].length == 0 48 Thread.critical = false 49 end 50 end 51end 52 53if __FILE__ == $0 54 ts = SimpleTupleSpace.new 55 clients = [] 56 servers = [] 57 58 def server(ts) 59 Thread.start { 60 loop do 61 req = ts.in('req') 62 ac = req[0] 63 num = req[1] 64 ts.out(ac, num * num) 65 end 66 } 67 end 68 69 def client(ts, n) 70 Thread.start { 71 ac = Object.new 72 ts.out('req', [ac, n]) 73 ans = ts.in(ac) 74 puts "#{n}: #{ans}" 75 } 76 end 77 78 3.times do 79 servers.push(server(ts)) 80 end 81 82 (1..6).each do |n| 83 clients.push(client(ts, n)) 84 end 85 86 clients.each do |t| 87 t.join 88 end 89end 90 91 92