开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
1 Star 0 Fork 0

source-code-analysis/python3.8.1

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
master
分支 (1)
master
master
分支 (1)
master
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
master
分支 (1)
master
python3.8.1
/
Doc
/
library
/
asyncio-task.rst
python3.8.1
/
Doc
/
library
/
asyncio-task.rst
asyncio-task.rst 27.99 KB
一键复制 编辑 原始数据 按行查看 历史
zhangweibo 提交于 2021年11月16日 09:46 +08:00 . git init
.. currentmodule:: asyncio


Coroutines and Tasks

This section outlines high-level asyncio APIs to work with coroutines and Tasks.

Coroutines

:term:`Coroutines <coroutine>` declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet of code (requires Python 3.7+) prints "hello", waits 1 second, and then prints "world":

>>> import asyncio

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

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

Note that simply calling a coroutine will not schedule it to be executed:

>>> main()
<coroutine object main at 0x1053bb7c8>

To actually run a coroutine, asyncio provides three main mechanisms:

  • The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.)

  • Awaiting on a coroutine. The following snippet of code will print "hello" after waiting for 1 second, and then print "world" after waiting for another 2 seconds:

    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())
    

    Expected output:

    started at 17:13:52
    hello
    world
    finished at 17:13:55
    
  • The :func:`asyncio.create_task` function to run coroutines concurrently as asyncio :class:`Tasks <Task>`.

    Let's modify the above example and run two say_after coroutines concurrently:

    async def main():
     task1 = asyncio.create_task(
     say_after(1, 'hello'))
    
     task2 = asyncio.create_task(
     say_after(2, 'world'))
    
     print(f"started at {time.strftime('%X')}")
    
     # Wait until both tasks are completed (should take
     # around 2 seconds.)
     await task1
     await task2
    
     print(f"finished at {time.strftime('%X')}")
    

    Note that expected output now shows that the snippet runs 1 second faster than before:

    started at 17:14:32
    hello
    world
    finished at 17:14:34
    

Awaitables

We say that an object is an awaitable object if it can be used in an :keyword:`await` expression. Many asyncio APIs are designed to accept awaitables.

There are three main types of awaitable objects: coroutines, Tasks, and Futures.

Coroutines

Python coroutines are awaitables and therefore can be awaited from other coroutines:

import asyncio

async def nested():
 return 42

async def main():
 # Nothing happens if we just call "nested()".
 # A coroutine object is created but not awaited,
 # so it *won't run at all*.
 nested()

 # Let's do it differently now and await it:
 print(await nested()) # will print "42".

asyncio.run(main())

Important

In this documentation the term "coroutine" can be used for two closely related concepts:

  • a coroutine function: an :keyword:`async def` function;
  • a coroutine object: an object returned by calling a coroutine function.

asyncio also supports legacy :ref:`generator-based <asyncio_generator_based_coro>` coroutines.

Tasks

Tasks are used to schedule coroutines concurrently.

When a coroutine is wrapped into a Task with functions like :func:`asyncio.create_task` the coroutine is automatically scheduled to run soon:

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:
 await task

asyncio.run(main())

Futures

A :class:`Future` is a special low-level awaitable object that represents an eventual result of an asynchronous operation.

When a Future object is awaited it means that the coroutine will wait until the Future is resolved in some other place.

Future objects in asyncio are needed to allow callback-based code to be used with async/await.

Normally there is no need to create Future objects at the application level code.

Future objects, sometimes exposed by libraries and some asyncio APIs, can be awaited:

async def main():
 await function_that_returns_a_future_object()

 # this is also valid:
 await asyncio.gather(
 function_that_returns_a_future_object(),
 some_python_coroutine()
 )

A good example of a low-level function that returns a Future object is :meth:`loop.run_in_executor`.

Running an asyncio Program

.. function:: run(coro, \*, debug=False)

 Execute the :term:`coroutine` *coro* and return the result.

 This function runs the passed coroutine, taking care of
 managing the asyncio event loop and *finalizing asynchronous
 generators*.

 This function cannot be called when another asyncio event loop is
 running in the same thread.

 If *debug* is ``True``, the event loop will be run in debug mode.

 This function always creates a new event loop and closes it at
 the end. It should be used as a main entry point for asyncio
 programs, and should ideally only be called once.

 Example::

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

 asyncio.run(main())

 .. versionadded:: 3.7


 .. note::
 The source code for ``asyncio.run()`` can be found in
 :source:`Lib/asyncio/runners.py`.

Creating Tasks

.. function:: create_task(coro, \*, name=None)

 Wrap the *coro* :ref:`coroutine <coroutine>` into a :class:`Task`
 and schedule its execution. Return the Task object.

 If *name* is not ``None``, it is set as the name of the task using
 :meth:`Task.set_name`.

 The task is executed in the loop returned by :func:`get_running_loop`,
 :exc:`RuntimeError` is raised if there is no running loop in
 current thread.

 This function has been **added in Python 3.7**. Prior to
 Python 3.7, the low-level :func:`asyncio.ensure_future` function
 can be used instead::

 async def coro():
 ...

 # In Python 3.7+
 task = asyncio.create_task(coro())
 ...

 # This works in all Python versions but is less readable
 task = asyncio.ensure_future(coro())
 ...

 .. versionadded:: 3.7

 .. versionchanged:: 3.8
 Added the ``name`` parameter.


Sleeping

.. coroutinefunction:: sleep(delay, result=None, \*, loop=None)

 Block for *delay* seconds.

 If *result* is provided, it is returned to the caller
 when the coroutine completes.

 ``sleep()`` always suspends the current task, allowing other tasks
 to run.

 .. deprecated-removed:: 3.8 3.10
 The *loop* parameter.

 .. _asyncio_example_sleep:

 Example of coroutine displaying the current date every second
 for 5 seconds::

 import asyncio
 import datetime

 async def display_date():
 loop = asyncio.get_running_loop()
 end_time = loop.time() + 5.0
 while True:
 print(datetime.datetime.now())
 if (loop.time() + 1.0) >= end_time:
 break
 await asyncio.sleep(1)

 asyncio.run(display_date())


Running Tasks Concurrently

.. awaitablefunction:: gather(\*aws, loop=None, return_exceptions=False)

 Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 sequence *concurrently*.

 If any awaitable in *aws* is a coroutine, it is automatically
 scheduled as a Task.

 If all awaitables are completed successfully, the result is an
 aggregate list of returned values. The order of result values
 corresponds to the order of awaitables in *aws*.

 If *return_exceptions* is ``False`` (default), the first
 raised exception is immediately propagated to the task that
 awaits on ``gather()``. Other awaitables in the *aws* sequence
 **won't be cancelled** and will continue to run.

 If *return_exceptions* is ``True``, exceptions are treated the
 same as successful results, and aggregated in the result list.

 If ``gather()`` is *cancelled*, all submitted awaitables
 (that have not completed yet) are also *cancelled*.

 If any Task or Future from the *aws* sequence is *cancelled*, it is
 treated as if it raised :exc:`CancelledError` -- the ``gather()``
 call is **not** cancelled in this case. This is to prevent the
 cancellation of one submitted Task/Future to cause other
 Tasks/Futures to be cancelled.

 .. deprecated-removed:: 3.8 3.10
 The *loop* parameter.

 .. _asyncio_example_gather:

 Example::

 import asyncio

 async def factorial(name, number):
 f = 1
 for i in range(2, number + 1):
 print(f"Task {name}: Compute factorial({i})...")
 await asyncio.sleep(1)
 f *= i
 print(f"Task {name}: factorial({number}) = {f}")

 async def main():
 # Schedule three calls *concurrently*:
 await asyncio.gather(
 factorial("A", 2),
 factorial("B", 3),
 factorial("C", 4),
 )

 asyncio.run(main())

 # Expected output:
 #
 # Task A: Compute factorial(2)...
 # Task B: Compute factorial(2)...
 # Task C: Compute factorial(2)...
 # Task A: factorial(2) = 2
 # Task B: Compute factorial(3)...
 # Task C: Compute factorial(3)...
 # Task B: factorial(3) = 6
 # Task C: Compute factorial(4)...
 # Task C: factorial(4) = 24

 .. versionchanged:: 3.7
 If the *gather* itself is cancelled, the cancellation is
 propagated regardless of *return_exceptions*.


Shielding From Cancellation

.. awaitablefunction:: shield(aw, \*, loop=None)

 Protect an :ref:`awaitable object <asyncio-awaitables>`
 from being :meth:`cancelled <Task.cancel>`.

 If *aw* is a coroutine it is automatically scheduled as a Task.

 The statement::

 res = await shield(something())

 is equivalent to::

 res = await something()

 *except* that if the coroutine containing it is cancelled, the
 Task running in ``something()`` is not cancelled. From the point
 of view of ``something()``, the cancellation did not happen.
 Although its caller is still cancelled, so the "await" expression
 still raises a :exc:`CancelledError`.

 If ``something()`` is cancelled by other means (i.e. from within
 itself) that would also cancel ``shield()``.

 If it is desired to completely ignore cancellation (not recommended)
 the ``shield()`` function should be combined with a try/except
 clause, as follows::

 try:
 res = await shield(something())
 except CancelledError:
 res = None

 .. deprecated-removed:: 3.8 3.10
 The *loop* parameter.


Timeouts

.. coroutinefunction:: wait_for(aw, timeout, \*, loop=None)

 Wait for the *aw* :ref:`awaitable <asyncio-awaitables>`
 to complete with a timeout.

 If *aw* is a coroutine it is automatically scheduled as a Task.

 *timeout* can either be ``None`` or a float or int number of seconds
 to wait for. If *timeout* is ``None``, block until the future
 completes.

 If a timeout occurs, it cancels the task and raises
 :exc:`asyncio.TimeoutError`.

 To avoid the task :meth:`cancellation <Task.cancel>`,
 wrap it in :func:`shield`.

 The function will wait until the future is actually cancelled,
 so the total wait time may exceed the *timeout*.

 If the wait is cancelled, the future *aw* is also cancelled.

 .. deprecated-removed:: 3.8 3.10
 The *loop* parameter.

 .. _asyncio_example_waitfor:

 Example::

 async def eternity():
 # Sleep for one hour
 await asyncio.sleep(3600)
 print('yay!')

 async def main():
 # Wait for at most 1 second
 try:
 await asyncio.wait_for(eternity(), timeout=1.0)
 except asyncio.TimeoutError:
 print('timeout!')

 asyncio.run(main())

 # Expected output:
 #
 # timeout!

 .. versionchanged:: 3.7
 When *aw* is cancelled due to a timeout, ``wait_for`` waits
 for *aw* to be cancelled. Previously, it raised
 :exc:`asyncio.TimeoutError` immediately.


Waiting Primitives

.. coroutinefunction:: wait(aws, \*, loop=None, timeout=None,\
 return_when=ALL_COMPLETED)

 Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 set concurrently and block until the condition specified
 by *return_when*.

 Returns two sets of Tasks/Futures: ``(done, pending)``.

 Usage::

 done, pending = await asyncio.wait(aws)

 *timeout* (a float or int), if specified, can be used to control
 the maximum number of seconds to wait before returning.

 Note that this function does not raise :exc:`asyncio.TimeoutError`.
 Futures or Tasks that aren't done when the timeout occurs are simply
 returned in the second set.

 *return_when* indicates when this function should return. It must
 be one of the following constants:

 .. tabularcolumns:: |l|L|

 +-----------------------------+----------------------------------------+
 | Constant | Description |
 +=============================+========================================+
 | :const:`FIRST_COMPLETED` | The function will return when any |
 | | future finishes or is cancelled. |
 +-----------------------------+----------------------------------------+
 | :const:`FIRST_EXCEPTION` | The function will return when any |
 | | future finishes by raising an |
 | | exception. If no future raises an |
 | | exception then it is equivalent to |
 | | :const:`ALL_COMPLETED`. |
 +-----------------------------+----------------------------------------+
 | :const:`ALL_COMPLETED` | The function will return when all |
 | | futures finish or are cancelled. |
 +-----------------------------+----------------------------------------+

 Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the
 futures when a timeout occurs.

 .. deprecated:: 3.8

 If any awaitable in *aws* is a coroutine, it is automatically
 scheduled as a Task. Passing coroutines objects to
 ``wait()`` directly is deprecated as it leads to
 :ref:`confusing behavior <asyncio_example_wait_coroutine>`.

 .. deprecated-removed:: 3.8 3.10

 The *loop* parameter.

 .. _asyncio_example_wait_coroutine:
 .. note::

 ``wait()`` schedules coroutines as Tasks automatically and later
 returns those implicitly created Task objects in ``(done, pending)``
 sets. Therefore the following code won't work as expected::

 async def foo():
 return 42

 coro = foo()
 done, pending = await asyncio.wait({coro})

 if coro in done:
 # This branch will never be run!

 Here is how the above snippet can be fixed::

 async def foo():
 return 42

 task = asyncio.create_task(foo())
 done, pending = await asyncio.wait({task})

 if task in done:
 # Everything will work as expected now.

 .. deprecated:: 3.8

 Passing coroutine objects to ``wait()`` directly is
 deprecated.


.. function:: as_completed(aws, \*, loop=None, timeout=None)

 Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws*
 set concurrently. Return an iterator of :class:`Future` objects.
 Each Future object returned represents the earliest result
 from the set of the remaining awaitables.

 Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
 all Futures are done.

 .. deprecated-removed:: 3.8 3.10
 The *loop* parameter.

 Example::

 for f in as_completed(aws):
 earliest_result = await f
 # ...


Scheduling From Other Threads

.. function:: run_coroutine_threadsafe(coro, loop)

 Submit a coroutine to the given event loop. Thread-safe.

 Return a :class:`concurrent.futures.Future` to wait for the result
 from another OS thread.

 This function is meant to be called from a different OS thread
 than the one where the event loop is running. Example::

 # Create a coroutine
 coro = asyncio.sleep(1, result=3)

 # Submit the coroutine to a given loop
 future = asyncio.run_coroutine_threadsafe(coro, loop)

 # Wait for the result with an optional timeout argument
 assert future.result(timeout) == 3

 If an exception is raised in the coroutine, the returned Future
 will be notified. It can also be used to cancel the task in
 the event loop::

 try:
 result = future.result(timeout)
 except asyncio.TimeoutError:
 print('The coroutine took too long, cancelling the task...')
 future.cancel()
 except Exception as exc:
 print(f'The coroutine raised an exception: {exc!r}')
 else:
 print(f'The coroutine returned: {result!r}')

 See the :ref:`concurrency and multithreading <asyncio-multithreading>`
 section of the documentation.

 Unlike other asyncio functions this function requires the *loop*
 argument to be passed explicitly.

 .. versionadded:: 3.5.1


Introspection

.. function:: current_task(loop=None)

 Return the currently running :class:`Task` instance, or ``None`` if
 no task is running.

 If *loop* is ``None`` :func:`get_running_loop` is used to get
 the current loop.

 .. versionadded:: 3.7


.. function:: all_tasks(loop=None)

 Return a set of not yet finished :class:`Task` objects run by
 the loop.

 If *loop* is ``None``, :func:`get_running_loop` is used for getting
 current loop.

 .. versionadded:: 3.7


Task Object

Generator-based Coroutines

Note

Support for generator-based coroutines is deprecated and is scheduled for removal in Python 3.10.

Generator-based coroutines predate async/await syntax. They are Python generators that use yield from expressions to await on Futures and other coroutines.

Generator-based coroutines should be decorated with :func:`@asyncio.coroutine <asyncio.coroutine>`, although this is not enforced.

.. decorator:: coroutine

 Decorator to mark generator-based coroutines.

 This decorator enables legacy generator-based coroutines to be
 compatible with async/await code::

 @asyncio.coroutine
 def old_style_coroutine():
 yield from asyncio.sleep(1)

 async def main():
 await old_style_coroutine()

 This decorator should not be used for :keyword:`async def`
 coroutines.

 .. deprecated-removed:: 3.8 3.10

 Use :keyword:`async def` instead.

.. function:: iscoroutine(obj)

 Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`.

 This method is different from :func:`inspect.iscoroutine` because
 it returns ``True`` for generator-based coroutines.

.. function:: iscoroutinefunction(func)

 Return ``True`` if *func* is a :ref:`coroutine function
 <coroutine>`.

 This method is different from :func:`inspect.iscoroutinefunction`
 because it returns ``True`` for generator-based coroutine functions
 decorated with :func:`@coroutine <coroutine>`.
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/python_sourcecode/python3.8.1.git
git@gitee.com:python_sourcecode/python3.8.1.git
python_sourcecode
python3.8.1
python3.8.1
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /