The goal of this task is to create a counting semaphore used to control the execution of a set of concurrent units. This task intends to demonstrate coordination of active concurrent units through the use of a passive concurrent unit. The operations for a counting semaphore are acquire, release, and count. Each active concurrent unit should attempt to acquire the counting semaphore before executing its assigned duties. In this case the active concurrent unit should report that it has acquired the semaphore. It should sleep for 2 seconds and then release the semaphore.

 
require 'thread'
 
# Simple Semaphore implementation
class Semaphore
  def initialize(size = 1)
    @queue = SizedQueue.new(size)
    size.times { acquire }
  end
 
  def acquire
    tap { @queue.push(nil) }
  end
 
  def release
    tap { @queue.pop }
  end
 
  # @return [Integer]
  def count
    @queue.length
  end
 
  def synchronize
    release
    yield
  ensure
    acquire
  end
end
 
def foo(id, sem)
  sem.synchronize do
    puts "Thread #{id} Acquired lock"
    sleep(2)
  end
end
 
threads = []
n = 5
s = Semaphore.new(3)
n.times do |i|
  threads << Thread.new { foo i, s }
end
threads.each(&:join)
 
 