code: def block_until_expired(timeout):
      
      if not callable(timeout):
          def dec(fn):
              @wraps(fn)
              def wrapper_(*args, **kwargs):
                  class TimeLimited(threading.Thread):
                      def __init__(self, _error=None, ):
                          threading.Thread.__init__(self)
                          self.error_ = _error
                          self.result = None
                          self.stopped = False
  
                      def run(self):
                          self.result = fn(*args, **kwargs)
  
                  try:
                      float(timeout)
                  except ValueError as err:
                      print('err: ', err)
                      return None, None
  
                  t = TimeLimited()
                  t.start()
  
                  if timeout > 0:
                      t.join(timeout)
  
                      if t.isAlive():
                          print('[timeout running out for {}]'.format(fn.__name__))
                          _async_raise(t.ident, SystemExit)
                          return None, None
  
                      return t.error_, t.result
  
              return wrapper_
  
          return dec
docs: 阻塞当前程序运行, 直到超时
  
      .. note: 会阻塞当前程序运行
  
      - 如果 ``timeout大于0``, 则当作 ``计时阻塞器`` 来使用
  
      .. code:: python
  
              @run_until(0.1)
              def s2():
                  m = 5
                  while m:
                      print('s2: ', m, now())
                      time.sleep(1)
                      m -= 1
                  return 'good'
  
      :param timeout: int
      :type timeout:
      :return:
      :rtype: