【问题标题】:What is the python equivalent of future/promise (threading)?什么是未来/承诺(线程)的python等价物?
【发布时间】:2021-07-08 22:41:18
【问题描述】:

我来自 C++ 世界,我正在寻找 Python 中的 std::future、std::promise 等价物。 Python中是否有等效的机制或另一种方法来实现相同的功能? 我知道 asyncio.Future,但我需要它来处理线程而不是 asyncio。

我正在使用我直接从我的主线程调用的第三方库 (PJSUA2),但它在由库创建的工作线程的上下文中以异步回调的形式发送结果。

期待 Python 的未来/承诺支持,我希望像这样编写我的应用程序代码:

future = wrap_foo(...)
if (future.get() != expected_result):
  throw Exception(...)

future1 = wrap_foo(...)
future2 = wrap_bar(...)

我计划用 wrap_xxx 函数(其中库函数称为 xxx)包装所有库异步调用,以负责创建未来/承诺对象。

我需要拥有多个未决未来的能力,所以我不能简单地制作同步 wrap_xxx 函数,在结果准备好之前阻塞。

【问题讨论】:

  • C++ 世界是否也因人类极端的无知和否认而遭受危险的气候变化?告诉我们更多关于你来自这个地方的信息:D
  • @木兰。想了解更多关于哥本哈文的信息?

标签: python multithreading promise future


【解决方案1】:

查看asyncio 模块-

import asyncio

async def main():
    print('hello')
    await asyncio.sleep(1)
    print('world')

asyncio.run(main())
hello
world

支持coroutines-

import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    print(f"started at {time.strftime('%X')}")

    await say_after(1, 'hello')
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())
started at 17:13:52
hello
world
finished at 17:13:55

还有tasks-

import asyncio

async def nested():
    return 42

async def main():
    # Schedule nested() to run soon concurrently
    # with "main()".
    task = asyncio.create_task(nested())

    # "task" can now be used to cancel "nested()", or
    # can simply be awaited to wait until it is complete:
    print(await task)

asyncio.run(main())
42

还有Futures-

import asyncio

async def set_after(fut, delay, value):
    # Sleep for *delay* seconds.
    await asyncio.sleep(delay)

    # Set *value* as a result of *fut* Future.
    fut.set_result(value)

async def main():
    # Get the current event loop.
    loop = asyncio.get_running_loop()

    # Create a new Future object.
    fut = loop.create_future()

    # Run "set_after()" coroutine in a parallel Task.
    # We are using the low-level "loop.create_task()" API here because
    # we already have a reference to the event loop at hand.
    # Otherwise we could have just used "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Wait until *fut* has a result (1 second) and print it.
    print(await fut)

asyncio.run(main())
hello ...
... world

【讨论】:

  • 我看不到 asyncio 如何适用于我的情况。我需要将信息从一个线程传递到另一个线程。图书馆正在对我强加线程。
  • 您需要在线程之间传递信息,而库正在向您强加线程?协程可以运行任意代码并相互通信。我不明白你的评论。
  • 我正在使用一个库(pjsua2),它从我获得回调(常规函数调用)的地方启动它自己的线程。我需要将这些事件转移到可以处理它们的主线程。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 2016-06-30
  • 2011-09-03
  • 2011-03-07
  • 1970-01-01
  • 2021-06-19
  • 2013-10-18
  • 2019-04-02
相关资源
最近更新 更多