class_docstr: A lock that can be acquired a fixed number of times before blocking.
  
  A Semaphore manages a counter representing the number of `.release` calls
  minus the number of `.acquire` calls, plus an initial value. The `.acquire`
  method blocks if necessary until it can return without making the counter
  negative.
  
  Semaphores limit access to a shared resource. To allow access for two
  workers at a time:
  
  .. testsetup:: semaphore
  
     from collections import deque
  
     from tornado import gen
     from tornado.ioloop import IOLoop
     from tornado.concurrent import Future
  
     # Ensure reliable doctest output: resolve Futures one at a time.
     futures_q = deque([Future() for _ in range(3)])
  
     @gen.coroutine
     def simulator(futures):
         for f in futures:
             yield gen.moment
             f.set_result(None)
  
     IOLoop.current().add_callback(simulator, list(futures_q))
  
     def use_some_resource():
         return futures_q.popleft()
  
  .. testcode:: semaphore
  
      from tornado import gen
      from tornado.ioloop import IOLoop
      from tornado.locks import Semaphore
  
      sem = Semaphore(2)
  
      @gen.coroutine
      def worker(worker_id):
          yield sem.acquire()
          try:
              print("Worker %d is working" % worker_id)
              yield use_some_resource()
          finally:
              print("Worker %d is done" % worker_id)
              sem.release()
  
      @gen.coroutine
      def runner():
          # Join all workers.
          yield [worker(i) for i in range(3)]
  
      IOLoop.current().run_sync(runner)
  
  .. testoutput:: semaphore
  
      Worker 0 is working
      Worker 1 is working
      Worker 0 is done
      Worker 2 is working
      Worker 1 is done
      Worker 2 is done
  
  Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until
  the semaphore has been released once, by worker 0.
  
  `.acquire` is a context manager, so ``worker`` could be written as::
  
      @gen.coroutine
      def worker(worker_id):
          with (yield sem.acquire()):
              print("Worker %d is working" % worker_id)
              yield use_some_resource()
  
          # Now the semaphore has been released.
          print("Worker %d is done" % worker_id)
  
  In Python 3.5, the semaphore itself can be used as an async context
  manager::
  
      async def worker(worker_id):
          async with sem:
              print("Worker %d is working" % worker_id)
              await use_some_resource()
  
          # Now the semaphore has been released.
          print("Worker %d is done" % worker_id)
  
  .. versionchanged:: 4.3
     Added ``async with`` support in Python 3.5.
class_docstr_tok: ["A","lock","that","can","be","acquired","a","fixed","number","of","times","before","blocking",".","A","Semaphore","manages","a","counter","representing","the","number","of","`",".release","`","calls","minus","the","number","of","`",".acquire","`","calls",",","plus","an","initial","value",".","The","`",".acquire","`","method","blocks","if","necessary","until","it","can","return","without","making","the","counter","negative",".","Semaphores","limit","access","to","a","shared","resource",".","To","allow","access","for","two","workers","at","a","time",":","..","testsetup",":",":","semaphore","from","collections","import","deque","from","tornado","import","gen","from","tornado.ioloop","import","IOLoop","from","tornado.concurrent","import","Future","#","Ensure","reliable","doctest","output",":","resolve","Futures","one","at","a","time",".","futures_q","=","deque","(","[","Future","(",")","for","_","in","range","(","3",")","]",")","@","gen.coroutine","def","simulator","(","futures",")",":","for","f","in","futures",":","yield","gen.moment","f.set_result","(","None",")","IOLoop.current","(",")",".add_callback","(","simulator",",","list","(","futures_q",")",")","def","use_some_resource","(",")",":","return","futures_q.popleft","(",")","..","testcode",":",":","semaphore","from","tornado","import","gen","from","tornado.ioloop","import","IOLoop","from","tornado.locks","import","Semaphore","sem","=","Semaphore","(","2",")","@","gen.coroutine","def","worker","(","worker_id",")",":","yield","sem.acquire","(",")","try",":","print","(","``","Worker","%","d","is","working","''","%","worker_id",")","yield","use_some_resource","(",")","finally",":","print","(","``","Worker","%","d","is","done","''","%","worker_id",")","sem.release","(",")","@","gen.coroutine","def","runner","(",")",":","#","Join","all","workers",".","yield","[","worker","(","i",")","for","i","in","range","(","3",")","]","IOLoop.current","(",")",".run_sync","(","runner",")","..","testoutput",":",":","semaphore","Worker","0","is","working","Worker","1","is","working","Worker","0","is","done","Worker","2","is","working","Worker","1","is","done","Worker","2","is","done","Workers","0","and","1","are","allowed","to","run","concurrently",",","but","worker","2","waits","until","the","semaphore","has","been","released","once",",","by","worker","0",".","`",".acquire","`","is","a","context","manager",",","so","``","worker","``","could","be","written","as",":",":","@","gen.coroutine","def","worker","(","worker_id",")",":","with","(","yield","sem.acquire","(",")",")",":","print","(","``","Worker","%","d","is","working","''","%","worker_id",")","yield","use_some_resource","(",")","#","Now","the","semaphore","has","been","released",".","print","(","``","Worker","%","d","is","done","''","%","worker_id",")","In","Python","3.5",",","the","semaphore","itself","can","be","used","as","an","async","context","manager",":",":","async","def","worker","(","worker_id",")",":","async","with","sem",":","print","(","``","Worker","%","d","is","working","''","%","worker_id",")","await","use_some_resource","(",")","#","Now","the","semaphore","has","been","released",".","print","(","``","Worker","%","d","is","done","''","%","worker_id",")","..","versionchanged",":",":","4.3","Added","``","async","with","``","support","in","Python","3.5","."]
code: def __aexit__(self, typ, value, tb):
      self.release()
  
imports: from __future__ import absolute_import, division, print_function
  import collections
  from tornado import gen, ioloop
  from tornado.concurrent import Future
label_desc: Use image node_id 7 for calling the Semaphore obj's underlying member method code with example usage: obj.__aexit__(typ, value, tb) without return types