当前位置:   article > 正文

【Python】同步、异步、堵塞、非堵塞、回调_python阻塞和非阻塞

python阻塞和非阻塞

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。


一、Python中的同步异步

在 Python 中,同步和异步通常是指代码执行的模式。

同步:

程序执行同步操作时,程序将等待该操作完成,然后才执行下一段代码。这种模式被称为同步模式。在同步模式下,程序必须等待操作完成之后才能继续执行下一步操作。

异步:

在异步模式下,程序执行操作时,不需要等待该操作完成,而是可以继续执行其他操作。当该操作完成后,程序将通知其结果。这使得程序可以执行多个操作而不必等待每个操作完成。异步操作通常使用回调函数来处理操作结果。

在 Python 中,可以使用 async 和 await 关键字来实现异步操作。async 关键字用于定义异步函数,而 await 关键字用于等待异步函数的结果。异步函数通常返回一个协程对象,该对象可以在 await 关键字后使用。

另外,Python 还提供了 asyncio 模块来实现异步操作,该模块提供了事件循环和协程的支持。使用事件循环可以管理多个协程,而协程可以在事件循环中运行,以实现非阻塞的 I/O 操作。

二、Python中的堵塞非堵塞

在 Python 中,堵塞和非堵塞通常是指 I/O 操作的模式。

堵塞:

当程序执行 I/O 操作时,程序将等待 I/O 操作完成后再执行接下来的代码。这种模式被称为堵塞模式。在这种模式下,直到 I/O 操作完成之前,程序无法执行其他任务。

非堵塞:

在非堵塞模式下,程序执行 I/O 操作时,如果操作无法立即完成,则程序会立即返回,而不会等待操作完成。这使得程序可以执行其他任务,而不会被阻塞等待 I/O 操作完成。

在 Python 中,可以使用 socket 模块的 setblocking() 方法来设置套接字的堵塞和非堵塞模式。默认情况下,套接字是堵塞模式的。使用 setblocking(False) 将套接字设置为非堵塞模式。

另外,Python 还提供了 select、poll 和 epoll 等模块来实现非堵塞 I/O 操作,这些模块可以监视多个套接字的状态,并在有可读或可写数据时通知程序。这种方式可以使程序避免使用多线程或多进程来处理并发请求。

三、Python中的回调

在Python中,回调是一种常见的编程模式,用于异步或事件驱动编程。回调函数是一个函数对象,它被传递给其他函数作为参数,以便在完成某个任务时被调用。

回调函数通常在以下情况下使用:

  1. 异步编程:在异步编程中,回调函数用于在任务完成时通知程序,而不是等待任务完成。

例如,当使用Python的asyncio库时,可以定义一个回调函数,以便在异步任务完成时执行特定的操作。例如,当异步任务完成时,可以发送一条电子邮件或存储结果。

  1. 事件驱动编程:在事件驱动编程中,回调函数用于响应用户操作或系统事件。

例如,在Python的GUI编程中,可以定义回调函数,以便在用户单击按钮或输入文本时执行特定的操作。这些回调函数通常被绑定到GUI元素上,这样当用户与GUI元素交互时,就会自动调用回调函数。

总之,回调函数是Python中一种常见的编程模式,用于异步或事件驱动编程。通过使用回调函数,可以使程序更加灵活和可扩展。

示例
在 Python 中,使用 asyncio 库可以实现异步编程,而回调函数则是 asyncio 实现异步编程的基础。

在 asyncio 中,回调函数通常在以下情况下使用:

  1. 当一个异步任务完成时,可以通过调用回调函数来处理任务返回的结果。
import asyncio

def callback(future):
    print("Task completed: {}".format(future.result()))

async def coroutine():
    print("Start coroutine...")
    await asyncio.sleep(1)
    print("Coroutine completed.")
    return "Coroutine result."

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    future = asyncio.ensure_future(coroutine())
    future.add_done_callback(callback)
    loop.run_until_complete(future)
    loop.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在上面的代码中,我们定义了一个回调函数 callback,它将在异步任务完成时被调用。我们使用 asyncio.ensure_future 来创建一个 Future 对象,然后使用 add_done_callback 将回调函数与 Future 对象关联起来。当任务完成时,callback 函数将被调用,并打印任务的返回结果。

  1. 当一个异步任务发生异常时,可以通过调用回调函数来处理异常。
import asyncio

def callback(future):
    if future.exception() is not None:
        print("Task error: {}".format(future.exception()))
    else:
        print("Task result: {}".format(future.result()))

async def coroutine():
    print("Start coroutine...")
    await asyncio.sleep(1)
    raise ValueError("Coroutine error.")
    print("Coroutine completed.")
    return "Coroutine result."

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    future = asyncio.ensure_future(coroutine())
    future.add_done_callback(callback)
    loop.run_until_complete(future)
    loop.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在上面的代码中,我们将回调函数 callbackFuture 对象关联起来。当异步任务发生异常时,callback 函数将被调用,并打印异常信息。如果异步任务没有发生异常,则打印任务的返回结果。

总之,回调函数在 asyncio 中是一种非常重要的编程模式。通过使用回调函数,可以轻松地处理异步任务的返回结果和异常信息,使异步编程更加灵活和可扩展。

四、异步编程

Python 的异步编程可以使用 asyncio 模块来实现。在 asyncio 中,我们可以使用协程来实现异步编程。

具体步骤如下:

  1. 安装 asyncio 模块:

pip install asyncio

  1. 创建一个协程函数:
async def my_coroutine():
    # 异步操作的代码
    # 在这里可以使用异步 API,如 asyncio.sleep()
  • 1
  • 2
  • 3
  1. 在主函数中创建事件循环,并添加协程:
import asyncio

async def my_coroutine():
    # 异步操作的代码

loop = asyncio.get_event_loop()
loop.run_until_complete(my_coroutine())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. 在协程中使用异步 API:
import asyncio

async def my_coroutine():
    # 异步操作的代码
    await asyncio.sleep(1)  # 异步等待 1 秒钟

loop = asyncio.get_event_loop()
loop.run_until_complete(my_coroutine())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. 使用 asyncio.wait() 函数同时等待多个协程的完成:
import asyncio

async def coroutine1():
    # 异步操作的代码

async def coroutine2():
    # 异步操作的代码

async def coroutine3():
    # 异步操作的代码

loop = asyncio.get_event_loop()
tasks = [coroutine1(), coroutine2(), coroutine3()]
loop.run_until_complete(asyncio.wait(tasks))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

以上就是 Python 异步编程的基本步骤。在实际应用中,我们还可以使用 async with 和 async for 等语法来进行更加复杂的异步操作。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/102660
推荐阅读
相关标签
  

闽ICP备14008679号