3

我已经解决了一个多线程client调用一个域,每分钟一次有几个 HTTP 请求。基本上,每个 HTTP 都包装在客户端的单个线程中。使用连接池来管理套接字并重用它们connection class。不支持urllib3connection classasyncio

但有时,通常在长时间运行client(~24hrs)后,在发送请求时OSError: Too many open files会引发一些问题。connection class通常这些异常是在 id 大于 100k 的线程中捕获的......所以我认为我操作线程的方式是完全错误的。

示例代码如下所示。

def run():
  timer_start = time.time()
  workers = []
  # create several tasks in workers
  # i.e. workers.append(threading.Thread(target=foo, ...)
  run_workers(workers)
  timer = Time(timer_start - time.time() + 60, run)
  timer.start()

def run_workers(workers):
  i = 0
  while i < len(workers):
    if threading.active_count() < 8:
      workers[i].start()
      i += 1
    else:
      time.sleep(0.1)
  i = 0
  while len(workers):
    if i > len(workers):
      i = 0
    workers[i].join(timeout=0.1)
    if not workers[i].is_alive():
      del workers[i]
    i += 1

# A foo might do behavior like this
def foo(*args, **kwargs):
  res = pool.urlopen('POST', kwargs[url], kwargs[body], ...)
  if not (200 <= res.status < 300):
    #raise_error(...)    

#main()
run()

我的主要问题是我的方法是否足以在长期客户端中清理已完成的线程?我认为 python recycle used threads id 但为什么我仍然会得到一个运行 id > 100k 的线程?这是否意味着那些已经完成的线程仍然挂在那里?

4

0 回答 0