зеркало из https://github.com/github/ruby.git
92 строки
1.5 KiB
Ruby
92 строки
1.5 KiB
Ruby
|
#!/usr/local/bin/ruby
|
||
|
# SimpleTupleSpace
|
||
|
# Copyright (c) 1999-2000 Masatoshi SEKI
|
||
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
||
|
|
||
|
require 'thread'
|
||
|
|
||
|
class SimpleTupleSpace
|
||
|
def initialize
|
||
|
@hash = {}
|
||
|
@waiting = {}
|
||
|
@hash.taint
|
||
|
@waiting.taint
|
||
|
self.taint
|
||
|
end
|
||
|
|
||
|
def out(key, obj)
|
||
|
Thread.critical = true
|
||
|
@hash[key] ||= []
|
||
|
@waiting[key] ||= []
|
||
|
@hash[key].push obj
|
||
|
begin
|
||
|
t = @waiting[key].shift
|
||
|
@waiting.delete(key) if @waiting[key].length == 0
|
||
|
t.wakeup if t
|
||
|
rescue ThreadError
|
||
|
retry
|
||
|
ensure
|
||
|
Thread.critical = false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def in(key)
|
||
|
Thread.critical = true
|
||
|
@hash[key] ||= []
|
||
|
@waiting[key] ||= []
|
||
|
begin
|
||
|
loop do
|
||
|
if @hash[key].length == 0
|
||
|
@waiting[key].push Thread.current
|
||
|
Thread.stop
|
||
|
else
|
||
|
return @hash[key].shift
|
||
|
end
|
||
|
end
|
||
|
ensure
|
||
|
@hash.delete(key) if @hash[key].length == 0
|
||
|
Thread.critical = false
|
||
|
end
|
||
|
end
|
||
|
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
|
||
|
|
||
|
|