【问题标题】:Python Multithreading a for loop with limited ThreadsPython多线程一个有限线程的for循环
【发布时间】:2017-06-13 15:00:51
【问题描述】:

我只是在学习 Python,对多线程没有太多经验。我正在尝试通过 Requests session.post 方法发送一些 json。这在我需要遍历字典的许多 for 循环的底部的函数中调用。

有没有办法让它并行运行?

我还必须限制我的线程数,否则 post 调用会被阻塞,因为它们要彼此快速连接。帮助将不胜感激。

def doWork(session, List, RefHashList):
    for itemRefHash in RefHashList:
        for equipment in res['Response']['data']['items']:
            if equipment['itemHash'] == itemRefHash:
                if equipment['characterIndex'] != 0:
                    SendJsonViaSession(session, getCharacterIdFromIndex(res, equipment['characterIndex']), itemRefHash, equipment['quantity'])

【问题讨论】:

    标签: python multithreading python-requests


    【解决方案1】:

    首先,以不同的方式构建代码可能会提高速度,而不会增加线程的复杂性。

    def doWork(session, res, RefHashList):
        for equipment in res['Response']['data']['items']:
            i = equipment['itemHash']
            k = equipment['characterIndex']
            if i in RefHashList and k != 0:
                SendJsonViaSession(session, getCharacterIdFromIndex(res, k), i, equipment['quantity'])
    

    首先,我们将只查找equipment['itemHash']equipment['characterIndex'] 一次。

    您可以使用in 运算符,而不是显式循环RefHashList。这会将循环移动到 Python 虚拟机中,这样更快。

    您可以使用 and 来使用单个条件,而不是嵌套的 if-conditional。

    注意: 我已经删除了未使用的参数List,并将其替换为res。编写只作用于给定参数而不作用于全局变量的函数通常是一种好习惯。

    其次,您需要多少额外的性能? SendJsonViaSession 呼叫之间平均有多少时间,在呼叫被阻止之前,这个时间可以变得多短?如果这些数字之间的差异很小,则可能不值得实现线程发送器。

    第三,标准 Python 实现的一个设计特点是一次只有一个线程可以执行 Python 字节码。所以不确定线程​​是否会提高性能。

    编辑:

    有几种方法可以在 Python 中并行运行。 multiprocessing.Pool 使用进程,multiprocessing.dummy.ThreadPool 使用线程。并且从 Python 3.2 开始有了concurrent.futures,它可以使用进程或线程。

    问题是,它们都没有速率限制。因此,您可能会因拨打太多电话而被阻止。 每次调用SendJsonViaSession 时,您都必须以某种方式保存当前时间,以便所有进程或线程都可以使用它。在每次通话之前,您必须读取该时间并等待它是否离上次通话太近。

    编辑2:

    如果调用SendJsonViaSession 只需要 0.3 秒,您应该可以连续进行 3 次调用/秒。但是您的代码每秒只调用 1 次。这意味着速度限制在其他地方。你必须profile你的代码才能看到问题出在哪里。

    【讨论】:

    • 太棒了。感谢您提供快速而翔实的帮助。我可以在 10 秒内拨打 250 次电话,否则油门会启动,我会被阻塞。现在我在 10 秒内发送大约 10 个电话。所以可能会有改进的潜力。
    • @LeoldeWire 调用SendJsonViaSession 实际需要多长时间?
    • ~0.3 秒我会说
    • @LeoldeWire 通过line profiler 运行您的代码。这样你就可以看到哪些行实际上运行时间最长。然后你知道什么要优化
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 2016-12-15
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多