Python 使用线程进行500000个api调用?

Python 使用线程进行500000个api调用?,python,multithreading,Python,Multithreading,我正在尝试使用对内部系统API的API调用获取多个客户端的数据(csv文件的详细信息)。目前,它告诉我,对于平均超过1000个API调用,运行15个线程时的响应时间是0.6691秒。在50万个请求的过程中,这将总计约93个小时。我的代码没有太多API细节,如下所示: def get_file(): count = -1 freader = open(f_name, 'rU') csvreader = csv.reader(freader) for row in c

我正在尝试使用对内部系统API的API调用获取多个客户端的数据(csv文件的详细信息)。目前,它告诉我,对于平均超过1000个API调用,运行15个线程时的响应时间是0.6691秒。在50万个请求的过程中,这将总计约93个小时。我的代码没有太多API细节,如下所示:

def get_file():
    count = -1
    freader = open(f_name, 'rU')
    csvreader = csv.reader(freader)
    for row in csvreader:
        userid = str(row[0])
        count += 1
        while (activeCount() > 15):
            time.sleep(10)
            continue
        thread = Thread(target=check, args=(userid, count,))
        thread.start()
        # check(userid)
    thread.join()


def check(userid, count):
    headers = {
        'Accept': '*/*',
        'Authorization': authStr,
        'accept-encoding': 'gzip, deflate'
    }
    url = "{}{}/{}/{}".format(api_url, site_id, id_type, userid)
    response = requests.get(url, headers=headers)
    if response.status_code == 404:
        viewed_count = 0
    else:
        viewed_count = json_extract(response.json())

我怎样才能加快速度?我可以指定的
线程(activeCount)
的最大数量是多少?还有更简单、更快、更优雅的方法吗?

尽管Python中的线程由于GIL限制而不能同时运行(旁注),但线程可能会有所帮助,因为响应会阻塞当前线程,但不需要计算,因此线程被设为睡眠状态。
在此期间,另一个线程可以发出请求。

试着找到你想要请求的线程的最佳位置。

谢谢。我就是这么做的。目前正在运行200个线程。每个API的时间减少到“每个请求的平均时间:0.058228353313秒”。最初尝试了500个线程,但请求引发了错误。您知道安全使用的线程数量是否有上限吗?更多线程并不一定意味着性能更好(在您的护理请求中)。也可能存在争议和其他限制。此外,服务器可能会限制每个客户端/ipWhere/when is
get_file()
调用的请求量?当它加入
线程时
它所在的任何线程都将不再能够执行(当GIL被其他线程释放时,或者在每这么多字节码指令或固定时间间隔后抢占,具体取决于Python版本)。保持尽可能多的线程处于可运行状态将有助于他们更快地完成工作。@martineau get_file()是程序的入口点,获取Auth0访问权限、文件检查等需要一系列检查条件和一些其他API调用。完成所有这些后,get_file()将调用,它在API调用上循环,并从.csv文件中获取调用的详细信息。我尝试了一系列的组合,确定线程数为200。。。这将时间从大约90个小时减少到大约4个小时。好的,但我认为您在最后执行的
thread.join()
是错误的。它什么也不做,只是等待在前面的
for
循环中创建的最后一个
线程
实例结束它们。如果需要
get_file()
等待创建的所有线程完成,则需要创建所有线程的列表并等待它们全部完成。更好的方法可能是使用
ThreadPool
。请看下面的代码示例。事实上,在查看已接受的答案后,使用(可能是
BoundedSemaphore
)可能是一种更好的方法,假设您的代码可以进行修改以使用它们。Thank@martineau将在接下来的几个实例中实现这一点。然而,目前我的程序似乎运行良好。我同意当前形式的thread.join()只会等待最后一个实例的结束,这就是本例的要点。get_file()是一条死胡同,除此之外没有其他函数。我在这里使用线程来并行运行多个API请求。完成最后一个线程后,脚本将完成运行。正如您正确提到的,ThreadPool可能是在不增加信号量复杂性的情况下实现这一点的正确方法。