Created
July 24, 2010 20:01
-
-
Save panaggio/488926 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Semaphore | |
# | |
# Creates a new Semaphore | |
# | |
def initialize(initvalue = 0) | |
@counter = @max = initvalue | |
@waiting = [] | |
@mutex = Mutex.new | |
end | |
# | |
# Attempts to enter and waits if the semaphore is already full | |
# | |
def wait | |
@mutex.lock | |
if (@counter -= 1) < 0 | |
@waiting.push(Thread.current) | |
Thread.stop | |
end | |
ensure | |
@mutex.unlock | |
end | |
alias down wait | |
# | |
# Leaves and let another thread in, if there's any waiting | |
# | |
def signal | |
@mutex.lock | |
begin | |
#if (@counter = [@counter+1,@max].min) <= 0 | |
if (@counter += 1) <= 0 | |
t = @waiting.shift | |
t.wakeup if t | |
end | |
rescue ThreadError | |
retry | |
end | |
ensure | |
@mutex.unlock | |
end | |
alias up signal | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sem.rb:5:in `block in <main>' | |
sleep | |
/tmp/ruby/lib/ruby/1.9.1/thread.rb:50:in `wait' | |
sem.rb:6:in `block in <main>' | |
sleep | |
/tmp/ruby/lib/ruby/1.9.1/thread.rb:62:in `signal' | |
sem.rb:5:in `block in <main>' | |
sleep | |
/tmp/ruby/lib/ruby/1.9.1/thread.rb:50:in `wait' | |
sem.rb:6:in `block in <main>' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "thread" | |
s = Semaphore.new(1) | |
t1 = Thread.new { s.down; Thread.stop; s.up } | |
t2 = Thread.new { s.down; puts "It works" } | |
puts t1.status | |
puts t1.backtrace | |
puts t2.status | |
puts t2.backtrace | |
t1.run | |
puts t1.status | |
puts t1.backtrace | |
puts t2.status | |
puts t2.backtrace |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment