【问题标题】:How to use multiple threadpools in twisted with coroutines如何在扭曲的协同程序中使用多个线程池
【发布时间】:2021-01-17 12:43:49
【问题描述】:

我想在 Python Twisted 中使用一个单独的线程池来完成一些对 CPU 使用率要求很高的特殊工作。

我要执行的函数都定义为inlineCallback,我不能修改。

from twisted.python.threadpool import ThreadPool

@inflineCallbacks
def myFunc(i):
    tmp_result = yield intenseCPUwork(i)
    # more work ...
    return result

pool = ThreadPool(0, 2)

for i in range(100):
    pool.callInThread(myFunc, i)

...

但是由于我的函数返回一个 deferred,它们在线程池中像这样调用时会立即返回,从而导致所有 100 个调用一次执行,即使线程池的大小仅为 2。

如何确保在 twisted 中同时只调用两个异步函数?

【问题讨论】:

  • 您知道运行 Python 代码的多个线程在单个 CPU 内核上竞争执行吗?
  • 是的,我是。 strongCPUWork 函数会打开 deferedToThread 的子进程。它们还可能触发其他计算机上的工作负载。
  • 混合多线程和多处理?这是灾难的秘诀。不过,Twisted 有进程管理 API。使用那些而不是线程,你会没事的。
  • 我投票结束,因为这个问题实际上没有包含足够的信息来提供一个很好的例子。我建议编辑它以包含所有相关信息,然后也许有人可以提供一个很好的答案!
  • 感谢您的 cmets!我将避免灾难并找到一种更自然的方法来处理它,而不是试图将这种方法强制转换为工作版本。

标签: python twisted


【解决方案1】:

我要执行的函数都定义为inlineCallback,我不能修改。

这意味着您不能在非反应器线程中运行它们。除了几个例外(主要与日志记录或线程管理有关),Twisted API 不是线程安全的。您只能在反应器运行的同一线程中使用它们。

如果您无法更改目标函数以停止使用 Twisted API,则无法在另一个线程中运行它们。

【讨论】:

    【解决方案2】:

    我相信您需要的是异步/等待功能的支持以进行激烈的工作,如下所示

    import asyncio
    
    async def myFunc(i):
        tmp_result = yield intenseCPUwork(i)
        # more work ...
        return result
    
    loop = asyncio.get_event_loop()
    tasks = [
        loop.create_task(myFunc(1)),
        loop.create_task(myFunc(2))
    ]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 2011-05-17
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    相关资源
    最近更新 更多