我正在使用 Python requests 包向 API 发出大量请求。然而,在某些时候,我的程序由于“打开的文件太多”而崩溃。当我明确关闭我的会话时,我真的不知道这是怎么回事。
我使用以下代码:
import requests
import multiprocessing
import numpy as np
s = requests.session()
s.keep_alive = False
def request(i, mapId, minx, maxx, miny, maxy):
print(i)
try:
with requests.Session() as s:
r = s.post(
url + "metadata/polygons",
timeout=10,
json={
"mapId": mapId,
"layer": "percelen",
"xMin": minx,
"xMax": maxx,
"yMin": miny,
"yMax": maxy,
},
)
out = r.json()
s.close()
except:
print("something went wrong with: " + str(i))
for i in np.aragne(10000):
time.sleep(1)
multiprocessing.Process(target=request, args=argsList[i])
任何帮助或见解将不胜感激,因为我没有想法。
错误“打开的文件太多”表明的程序打开了太多文件,并且没有关闭它们或同时打开了太多文件。虽然的代码包含关闭请求会话的机制,但有一些改进可以解决该问题并优化的代码:
-
从
request
函数中删除requests.Session()
:无需为每个请求创建一个新会话。相反,请创建一个全局会话并在所有请求中重用它。这将减少创建和销毁过多会话的开销。 -
使用
multiprocessing.Pool
管理进程 :multiprocessing.Pool
提供了一种管理多个进程的更好方法,包括在任务完成时自动关闭进程。 -
使用
with
语句进行进程管理 :with
语句可以确保即使出现异常也能正确关闭资源(在本例中为进程)。
这是经过修改的代码:
import requests
import multiprocessing
import numpy as np
import time
# 全局会话
s = requests.Session()
s.keep_alive = False
url = "your_url" # 用的实际 URL 替换
def request(args):
i, mapId, minx, maxx, miny, maxy = args
print(i)
try:
with s.post(
url + "metadata/polygons",
timeout=10,
json={
"mapId": mapId,
"layer": "percelen",
"xMin": minx,
"xMax": maxx,
"yMin": miny,
"yMax": maxy,
},
) as r:
out = r.json()
except Exception as e:
print(f"出现错误:{e}")
if __name__ == "__main__":
argsList = [(i, mapId, minx, maxx, miny, maxy) for i in np.arange(10000)] # 创建 argsList
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
pool.map(request, argsList)
此代码首先创建一个全局会话 (
s
),该会话在所有请求中共享。然后,它定义了
request
函数,该函数现在接收一个参数元组,并使用全局会话发出请求。
主代码使用
multiprocessing.Pool
创建一个进程池。
Pool.map
方法用于将
request
函数并行应用于
argsList
中的每个参数集。
with
语句确保在池完成其工作后将其正确关闭,从而释放资源并防止“打开的文件太多”错误。
此改进后的代码应解决文件描述符泄漏并提高代码的整体效率。请记住根据的特定需求调整进程数。
标签:python,python-requests From: 55230576