code: def using(self, num_instances: int = 1, timeout: Optional[float] = None):
          
          self.take(num_instances, timeout)
          yield self
          self.release(num_instances)
docs: Context manager around resource reservation: when the code block under the with statement is entered, the
          current process holds the instances it requested. When it exits, all these instances are released.
  
          Do not explicitly `release()` instances within the context block, at the risk of breaking instance management.
          If one needs to `release()` instances piecemeal, it should instead reserve the instances using `take()`.
  
          :param num_instances:
              Number of resource instances to take.
          :param timeout:
              If this parameter is not ``None``, it is taken as a delay at the end of which the process times out, and
              leaves the queue forcibly. In such a situation, a :py:class:`Timeout` exception is raised on the process.