#!/usr/local/bin/ruby # SimpleTupleSpace # $Id: simpletuple.rb,v 1.2 2000/02/05 07:14:43 mas Exp $ # $Author: mas $ # Copyright (c) 1999-2000 Masatoshi SEKI # You can redistribute it and/or modify it under the same term as Ruby. require 'thread' class SimpleTupleSpace def initialize @que = {} @waiting = {} @que.taint # enable tainted comunication @waiting.taint self.taint end def out(key, obj) Thread.critical = true @que[key] = [] unless @que[key] @waiting[key] = [] unless @waiting[key] @que[key].push obj t = @waiting[key].shift @waiting.delete(key) if @waiting[key].length == 0 Thread.critical = false t.run if t end alias put out def in(key, non_block=false) Thread.critical = true @que[key] = [] unless @que[key] @waiting[key] = [] unless @waiting[key] begin loop do if @que[key].length == 0 if non_block raise ThreadError, "queue empty" end @waiting[key].push Thread.current Thread.stop else return @que[key].shift end end ensure @que.delete(key) if @que[key].length == 0 Thread.critical = false end end alias get in end if __FILE__ == $0 ts = SimpleTupleSpace.new clients = [] servers = [] def server(ts) Thread.start { loop do req = ts.in('req') ac = req[0] num = req[1] ts.out(ac, num * num) end } end def client(ts, n) Thread.start { ac = Object.new ts.out('req', [ac, n]) ans = ts.in(ac) puts "#{n}: #{ans}" } end 3.times do servers.push(server(ts)) end (1..6).each do |n| clients.push(client(ts, n)) end clients.each do |t| t.join end end