Hướng dẫn why async await is used in python? - tại sao async đang chờ được sử dụng trong python?

Async IO là một thiết kế lập trình đồng thời đã nhận được sự hỗ trợ chuyên dụng trong Python, phát triển nhanh chóng từ Python 3,4 đến 3,7, và có lẽ hơn thế nữa.

Show

Bạn có thể đang suy nghĩ với sự sợ hãi, đồng thời, sự song song, luồng, đa xử lý. Đó là rất nhiều để nắm bắt. Async IO phù hợp ở đâu? ”

Hướng dẫn này được xây dựng để giúp bạn trả lời câu hỏi đó, mang đến cho bạn một sự nắm bắt vững chắc hơn về cách tiếp cận của Python, đối với Async IO.

Đây là những gì bạn bao gồm:

  • IO không đồng bộ (Async IO): Một mô hình không liên tục ngôn ngữ (mô hình) có các triển khai trên một loạt các ngôn ngữ lập trình: a language-agnostic paradigm (model) that has implementations across a host of programming languages

  • ________ 32/________ 33: Hai từ khóa Python mới được sử dụng để xác định coroutines: two new Python keywords that are used to define coroutines

  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4: Gói Python cung cấp nền tảng và API để chạy và quản lý coroutines: the Python package that provides a foundation and API for running and managing coroutines

Coroutines (các chức năng máy phát chuyên dụng) là trái tim của Async IO trong Python, và chúng tôi sẽ đi sâu vào chúng sau này.

Trước khi bạn bắt đầu, bạn sẽ cần chắc chắn rằng bạn đã thiết lập để sử dụng

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 và các thư viện khác được tìm thấy trong hướng dẫn này.

Thiết lập môi trường của bạn

Bạn sẽ cần Python 3.7 trở lên để theo dõi toàn bộ bài viết này, cũng như các gói

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
6 và
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
7:

$ python3.7 -m venv ./py37async
$ source ./py37async/bin/activate  # Windows: .\py37async\Scripts\activate.bat
$ pip install --upgrade pip aiohttp aiofiles  # Optional: aiodns

Để được trợ giúp trong việc cài đặt Python 3.7 và thiết lập môi trường ảo, hãy xem Hướng dẫn cài đặt & cài đặt Python 3 hoặc Primer môi trường ảo.

Với điều đó, hãy để nhảy vào.

Chế độ xem IO Async 10.000 feet

Async IO ít được biết đến hơn một chút so với anh em họ đã thử và đúng, đa xử lý và xâu chuỗi. Phần này sẽ cung cấp cho bạn một bức tranh đầy đủ hơn về Async IO là gì và làm thế nào nó phù hợp với cảnh quan xung quanh của nó.

Async IO phù hợp ở đâu?

Đồng thời và song song là những chủ đề mở rộng không dễ dàng lội vào. Mặc dù bài viết này tập trung vào Async IO và việc triển khai của nó trong Python, nhưng nó đáng để mất một phút để so sánh IO ASYNC với các đối tác của mình để có bối cảnh về cách Async IO phù hợp với câu đố lớn hơn, đôi khi chóng mặt.

Sự song song bao gồm thực hiện nhiều hoạt động cùng một lúc. Đa xử lý là một phương tiện để thực hiện song song và nó đòi hỏi phải truyền bá các nhiệm vụ trên máy tính các đơn vị xử lý trung tâm (CPU hoặc lõi). Đa xử lý là rất phù hợp cho các nhiệm vụ liên kết CPU: các vòng lặp

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
8 ràng buộc chặt chẽ và tính toán toán học thường rơi vào danh mục này. consists of performing multiple operations at the same time. Multiprocessing is a means to effect parallelism, and it entails spreading tasks over a computer’s central processing units (CPUs, or cores). Multiprocessing is well-suited for CPU-bound tasks: tightly bound
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
8 loops and mathematical computations usually fall into this category.

Đồng thời là một thuật ngữ rộng hơn một chút so với song song. Nó gợi ý rằng nhiều nhiệm vụ có khả năng chạy một cách chồng chéo. (Có một câu nói rằng đồng thời không bao hàm sự song song.) is a slightly broader term than parallelism. It suggests that multiple tasks have the ability to run in an overlapping manner. (There’s a saying that concurrency does not imply parallelism.)

Chủ đề là một mô hình thực thi đồng thời, theo đó nhiều luồng thay phiên nhau thực hiện các tác vụ. Một quá trình có thể chứa nhiều luồng. Python có một mối quan hệ phức tạp với luồng nhờ vào Gil của nó, nhưng điều đó vượt quá phạm vi của bài viết này. is a concurrent execution model whereby multiple threads take turns executing tasks. One process can contain multiple threads. Python has a complicated relationship with threading thanks to its GIL, but that’s beyond the scope of this article.

Điều quan trọng để biết về luồng là nó tốt hơn cho các nhiệm vụ ràng buộc IO. Mặc dù một nhiệm vụ liên kết CPU được đặc trưng bởi các lõi máy tính liên tục làm việc chăm chỉ từ đầu đến cuối, một công việc ràng buộc IO bị chi phối bởi rất nhiều sự chờ đợi về đầu vào/đầu ra để hoàn thành.

Để tóm tắt lại những điều trên, đồng thời bao gồm cả đa xử lý (lý tưởng cho các tác vụ gắn CPU) và luồng (phù hợp cho các tác vụ gắn IO). Đa xử lý là một hình thức song song, với sự song song là một loại (tập hợp con) cụ thể của đồng thời. Thư viện tiêu chuẩn Python đã cung cấp hỗ trợ lâu dài cho cả hai gói này thông qua các gói

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
9,
$ python3 countsync.py
One
Two
One
Two
One
Two
countsync.py executed in 3.01 seconds.
0 và
$ python3 countsync.py
One
Two
One
Two
One
Two
countsync.py executed in 3.01 seconds.
1.

Bây giờ, thời gian để đưa một thành viên mới vào hỗn hợp. Trong vài năm qua, một thiết kế riêng biệt đã được tích hợp toàn diện hơn vào CPython: IO không đồng bộ, được bật thông qua gói thư viện tiêu chuẩn ____ ____34 và từ khóa ngôn ngữ

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2 và
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 mới. Để rõ ràng, Async IO không phải là một khái niệm mới được phát minh và nó đã tồn tại hoặc đang được tích hợp vào các ngôn ngữ và môi trường thời gian chạy khác, chẳng hạn như Go, C#hoặc Scala.

Gói

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 được lập hóa đơn bởi tài liệu Python như một thư viện để viết mã đồng thời. Tuy nhiên, Async IO không phải là luồng, cũng không phải là đa xử lý. Nó không được xây dựng trên đầu của một trong hai.

Trên thực tế, Async IO là một thiết kế đơn, đơn, nó sử dụng đa nhiệm hợp tác, một thuật ngữ mà bạn sẽ đưa ra vào cuối hướng dẫn này. Nói cách khác, người ta đã nói rằng Async IO mang lại cảm giác đồng thời mặc dù sử dụng một luồng duy nhất trong một quy trình. Coroutines (một tính năng trung tâm của Async IO) có thể được lên lịch đồng thời, nhưng chúng không đồng thời.cooperative multitasking, a term that you’ll flesh out by the end of this tutorial. It has been said in other words that async IO gives a feeling of concurrency despite using a single thread in a single process. Coroutines (a central feature of async IO) can be scheduled concurrently, but they are not inherently concurrent.

Để nhắc lại, Async IO là một phong cách lập trình đồng thời, nhưng nó không phải là song song. Nó phù hợp chặt chẽ hơn với việc xâu chuỗi so với đa xử lý nhưng rất khác biệt với cả hai điều này và là một thành viên độc lập trong túi thủ thuật đồng thời.

Điều đó để lại một thuật ngữ nữa. Nó có ý nghĩa gì đối với một cái gì đó không đồng bộ? Đây là một định nghĩa nghiêm ngặt, nhưng với mục đích của chúng tôi ở đây, tôi có thể nghĩ về hai thuộc tính:asynchronous? This isn’t a rigorous definition, but for our purposes here, I can think of two properties:

  • Các thói quen không đồng bộ có thể tạm dừng trong khi chờ đợi kết quả cuối cùng của họ và để các thói quen khác chạy trong lúc này.
  • Mã không đồng bộ, thông qua cơ chế ở trên, tạo điều kiện thực hiện đồng thời. Nói cách khác, mã không đồng bộ mang lại cái nhìn và cảm giác đồng thời.

Ở đây, một sơ đồ để đặt tất cả lại với nhau. Các thuật ngữ màu trắng đại diện cho các khái niệm và các thuật ngữ xanh biểu thị các cách mà chúng được thực hiện hoặc thực hiện:

Hướng dẫn why async await is used in python? - tại sao async đang chờ được sử dụng trong python?

Tôi sẽ dừng lại ở đó về sự so sánh giữa các mô hình lập trình đồng thời. Hướng dẫn này tập trung vào thành phần phụ là async io, cách sử dụng nó và các API đã xuất hiện xung quanh nó. Để khám phá kỹ lưỡng về luồng so với đa xử lý so với Async IO, tạm dừng ở đây và kiểm tra tổng quan về Jim Anderson về sự đồng thời trong Python. Jim là người hài hước hơn tôi và đã ngồi trong nhiều cuộc họp hơn tôi, để khởi động.

Async IO giải thích

Async IO lúc đầu có vẻ phản trực giác và nghịch lý. Làm thế nào để một cái gì đó tạo điều kiện cho mã đồng thời sử dụng một luồng duy nhất và một lõi CPU duy nhất? Tôi không bao giờ giỏi trong việc gợi lên các ví dụ, vì vậy tôi đã muốn diễn giải một trong những bài nói chuyện của Miguel Grinberg, 2017, giải thích mọi thứ khá đẹp mắt:

Chess Master Judit Polgár tổ chức một triển lãm cờ vua, trong đó cô đóng vai nhiều người chơi nghiệp dư. Cô có hai cách tiến hành triển lãm: đồng bộ và không đồng bộ.

Assumptions:

  • 24 đối thủ
  • Judit làm cho mỗi cờ vua di chuyển trong 5 giây
  • Đối thủ mỗi người mất 55 giây để thực hiện một động thái
  • Trò chơi trung bình 30 cặp đôi (tổng số 60 động tác)

Phiên bản đồng bộ: Judit chơi một trò chơi tại một thời điểm, không bao giờ hai lần cùng một lúc, cho đến khi trò chơi hoàn tất. Mỗi trò chơi mất (55 + 5) * 30 == 1800 giây hoặc 30 phút. Toàn bộ triển lãm mất 24 * 30 == 720 phút, hoặc 12 giờ.: Judit plays one game at a time, never two at the same time, until the game is complete. Each game takes (55 + 5) * 30 == 1800 seconds, or 30 minutes. The entire exhibition takes 24 * 30 == 720 minutes, or 12 hours.

Phiên bản không đồng bộ: Judit di chuyển từ bảng này sang bảng khác, thực hiện một di chuyển ở mỗi bảng. Cô rời khỏi bàn và để đối thủ thực hiện bước đi tiếp theo của họ trong thời gian chờ đợi. Một động tác trên tất cả 24 trò chơi cần Judit 24 * 5 == 120 giây hoặc 2 phút. Toàn bộ triển lãm hiện được cắt giảm xuống còn 120 * 30 == 3600 giây, hoặc chỉ 1 giờ. (Nguồn): Judit moves from table to table, making one move at each table. She leaves the table and lets the opponent make their next move during the wait time. One move on all 24 games takes Judit 24 * 5 == 120 seconds, or 2 minutes. The entire exhibition is now cut down to 120 * 30 == 3600 seconds, or just 1 hour. (Source)

Chỉ có một Judit Polgár, người chỉ có hai tay và chỉ tự mình di chuyển một lần. Nhưng chơi không đồng bộ cắt giảm thời gian triển lãm giảm từ 12 giờ xuống một. Vì vậy, đa nhiệm hợp tác là một cách thú vị để nói rằng một vòng lặp sự kiện của chương trình (nhiều hơn về sau) giao tiếp với nhiều nhiệm vụ để cho mỗi lần thay phiên nhau chạy vào thời điểm tối ưu.

Async IO mất nhiều thời gian chờ đợi trong đó các chức năng sẽ bị chặn và cho phép các chức năng khác chạy trong thời gian ngừng hoạt động đó. (Một chức năng chặn hiệu quả cấm người khác chạy từ thời điểm bắt đầu cho đến khi nó trở lại.)

Async io không dễ dàng

Tôi đã nghe nó nói, sử dụng IO Async khi bạn có thể; Sử dụng luồng khi bạn phải. Sự thật là việc xây dựng mã đa luồng bền có thể khó và dễ bị lỗi. Async IO tránh được một số tốc độ tiềm năng mà bạn có thể gặp phải với một thiết kế ren.

Nhưng điều đó không thể nói rằng IO Async trong Python rất dễ dàng. Được cảnh báo: Khi bạn mạo hiểm thấp hơn một chút dưới mức bề mặt, chương trình Async cũng có thể khó khăn! Mô hình Async của Python, được xây dựng xung quanh các khái niệm như gọi lại, sự kiện, vận chuyển, giao thức và tương lai, chỉ có thuật ngữ có thể đáng sợ. Thực tế là API của nó đã thay đổi liên tục làm cho nó không dễ dàng hơn.

May mắn thay,

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 đã trưởng thành đến một điểm mà hầu hết các tính năng của nó không còn tạm thời, trong khi tài liệu của nó đã nhận được một cuộc đại tu rất lớn và một số tài nguyên chất lượng về chủ đề này cũng bắt đầu xuất hiện.

Gói #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 4 và ________ 32/________ 33

Bây giờ bạn có một số nền tảng về Async IO như một thiết kế, hãy để khám phá triển khai Python. Gói Python từ

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 (được giới thiệu trong Python 3.4) và hai từ khóa của nó,
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2 và
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3, phục vụ các mục đích khác nhau nhưng kết hợp với nhau để giúp bạn tuyên bố, xây dựng, thực thi và quản lý mã không đồng bộ.

________ 32/________ 33 Cú pháp và coroutines bản địa

Trọng tâm của Async IO là coroutines. Một coroutine là một phiên bản chuyên dụng của hàm tạo Python. Hãy bắt đầu với một định nghĩa cơ bản và sau đó xây dựng nó khi bạn tiến bộ ở đây: Coroutine là một chức năng có thể đình chỉ thực thi trước khi đạt

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
5 và nó có thể gián tiếp chuyển quyền kiểm soát cho một coroutine khác trong một thời gian.

Sau đó, bạn sẽ đi sâu hơn rất nhiều về cách chính xác trình tạo truyền thống được tái sử dụng thành một coroutine. Hiện tại, cách dễ nhất để chọn cách thức hoạt động của Coroutines là bắt đầu tạo ra một số.

Hãy để cách tiếp cận nhập vai và viết một số mã IO không đồng bộ. Chương trình ngắn này là

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
6 của Async IO nhưng đi một chặng đường dài để minh họa chức năng cốt lõi của nó:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")

Khi bạn thực hiện tệp này, hãy lưu ý những gì trông khác so với nếu bạn xác định các chức năng chỉ với

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
7 và
async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
8:

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.

Thứ tự của đầu ra này là trái tim của Async IO. Nói chuyện với từng cuộc gọi đến

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
9 là một vòng lặp sự kiện hoặc điều phối viên. Khi mỗi nhiệm vụ đạt đến
async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
0, chức năng hét lên với vòng lặp sự kiện và kiểm soát trở lại với nó, nói rằng, tôi sẽ ngủ trong 1 giây. Hãy tiếp tục và để một cái gì đó khác có ý nghĩa được thực hiện trong lúc này.

Tương phản điều này với phiên bản đồng bộ:

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")

Khi được thực hiện, có một thay đổi nhẹ nhưng quan trọng theo thứ tự và thời gian thực hiện:

$ python3 countsync.py
One
Two
One
Two
One
Two
countsync.py executed in 3.01 seconds.

Mặc dù sử dụng

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
8 và
async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
2 có vẻ tầm thường, nhưng chúng được sử dụng làm độc lập cho bất kỳ quy trình sử dụng nhiều thời gian nào liên quan đến thời gian chờ đợi. . Cũng mất một chút thời gian để hoàn thành).

Như bạn sẽ thấy trong phần tiếp theo, lợi ích của việc chờ đợi một cái gì đó, bao gồm

async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
2, là chức năng xung quanh có thể tạm thời giảm kiểm soát cho một chức năng khác mà Lôi có thể làm điều gì đó ngay lập tức. Ngược lại,
async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
8 hoặc bất kỳ cuộc gọi chặn nào khác không tương thích với mã Python không đồng bộ, bởi vì nó sẽ dừng mọi thứ trong các bài hát của nó trong suốt thời gian của thời gian ngủ.

Các quy tắc của async io

Tại thời điểm này, một định nghĩa chính thức hơn của

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2,
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 và các chức năng coroutine mà chúng tạo ra theo thứ tự. Phần này có một chút dày đặc, nhưng nhận được ____ 32/________ 33 là công cụ, vì vậy hãy quay lại điều này nếu bạn cần:

  • Cú pháp

    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    2 giới thiệu một coroutine gốc hoặc một máy phát không đồng bộ. Các biểu thức
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    3 và
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    4 cũng hợp lệ và bạn sẽ thấy chúng sau này.native coroutine or an asynchronous generator. The expressions
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    3 and
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    4 are also valid, and you’ll see them later on.

  • Từ khóa

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 chuyển kiểm soát chức năng trở lại vòng lặp sự kiện. . Được trả lại. Trong khi chờ đợi, hãy để một cái gì đó khác chạy.

Trong mã, điểm đạn thứ hai đó trông gần như thế này:

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r

Ngoài ra, còn có một bộ quy tắc nghiêm ngặt xung quanh khi nào và làm thế nào bạn có thể và không thể sử dụng ____ 32/________ 33. Chúng có thể hữu ích cho dù bạn vẫn đang chọn cú pháp hay đã tiếp xúc với việc sử dụng ________ 32/________ 33:

  • Một chức năng mà bạn giới thiệu với

    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    2 là một coroutine. Nó có thể sử dụng
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3,
    async def g():
        # Pause here and come back to g() when f() is ready
        r = await f()
        return r
    
    5 hoặc
    #!/usr/bin/env python3
    # rand.py
    
    import asyncio
    import random
    
    # ANSI colors
    c = (
        "\033[0m",   # End of color
        "\033[36m",  # Cyan
        "\033[91m",  # Red
        "\033[35m",  # Magenta
    )
    
    async def makerandom(idx: int, threshold: int = 6) -> int:
        print(c[idx + 1] + f"Initiated makerandom({idx}).")
        i = random.randint(0, 10)
        while i <= threshold:
            print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
            await asyncio.sleep(idx + 1)
            i = random.randint(0, 10)
        print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
        return i
    
    async def main():
        res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
        return res
    
    if __name__ == "__main__":
        random.seed(444)
        r1, r2, r3 = asyncio.run(main())
        print()
        print(f"r1: {r1}, r2: {r2}, r3: {r3}")
    
    8, nhưng tất cả những thứ này là tùy chọn. Tuyên bố
    #!/usr/bin/env python3
    # rand.py
    
    import asyncio
    import random
    
    # ANSI colors
    c = (
        "\033[0m",   # End of color
        "\033[36m",  # Cyan
        "\033[91m",  # Red
        "\033[35m",  # Magenta
    )
    
    async def makerandom(idx: int, threshold: int = 6) -> int:
        print(c[idx + 1] + f"Initiated makerandom({idx}).")
        i = random.randint(0, 10)
        while i <= threshold:
            print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
            await asyncio.sleep(idx + 1)
            i = random.randint(0, 10)
        print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
        return i
    
    async def main():
        res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
        return res
    
    if __name__ == "__main__":
        random.seed(444)
        r1, r2, r3 = asyncio.run(main())
        print()
        print(f"r1: {r1}, r2: {r2}, r3: {r3}")
    
    9 là hợp lệ:

    • Sử dụng

      #!/usr/bin/env python3
      # countsync.py
      
      import time
      
      def count():
          print("One")
          time.sleep(1)
          print("Two")
      
      def main():
          for _ in range(3):
              count()
      
      if __name__ == "__main__":
          s = time.perf_counter()
          main()
          elapsed = time.perf_counter() - s
          print(f"{__file__} executed in {elapsed:0.2f} seconds.")
      
      3 và/hoặc
      async def g():
          # Pause here and come back to g() when f() is ready
          r = await f()
          return r
      
      5 tạo ra chức năng coroutine. Để gọi chức năng coroutine, bạn phải
      #!/usr/bin/env python3
      # countsync.py
      
      import time
      
      def count():
          print("One")
          time.sleep(1)
          print("Two")
      
      def main():
          for _ in range(3):
              count()
      
      if __name__ == "__main__":
          s = time.perf_counter()
          main()
          elapsed = time.perf_counter() - s
          print(f"{__file__} executed in {elapsed:0.2f} seconds.")
      
      3 nó để có kết quả.

    • Nó ít phổ biến hơn (và chỉ gần đây hợp pháp trong Python) để sử dụng

      #!/usr/bin/env python3
      # rand.py
      
      import asyncio
      import random
      
      # ANSI colors
      c = (
          "\033[0m",   # End of color
          "\033[36m",  # Cyan
          "\033[91m",  # Red
          "\033[35m",  # Magenta
      )
      
      async def makerandom(idx: int, threshold: int = 6) -> int:
          print(c[idx + 1] + f"Initiated makerandom({idx}).")
          i = random.randint(0, 10)
          while i <= threshold:
              print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
              await asyncio.sleep(idx + 1)
              i = random.randint(0, 10)
          print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
          return i
      
      async def main():
          res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
          return res
      
      if __name__ == "__main__":
          random.seed(444)
          r1, r2, r3 = asyncio.run(main())
          print()
          print(f"r1: {r1}, r2: {r2}, r3: {r3}")
      
      8 trong một khối
      import asyncio
      
      @asyncio.coroutine
      def py34_coro():
          """Generator-based coroutine, older syntax"""
          yield from stuff()
      
      async def py35_coro():
          """Native coroutine, modern syntax"""
          await stuff()
      
      2. Điều này tạo ra một máy phát không đồng bộ, mà bạn lặp lại với
      import asyncio
      
      @asyncio.coroutine
      def py34_coro():
          """Generator-based coroutine, older syntax"""
          yield from stuff()
      
      async def py35_coro():
          """Native coroutine, modern syntax"""
          await stuff()
      
      4. Hãy quên đi các trình tạo async trong thời gian này và tập trung vào việc giảm cú pháp cho các chức năng coroutine, sử dụng
      #!/usr/bin/env python3
      # countsync.py
      
      import time
      
      def count():
          print("One")
          time.sleep(1)
          print("Two")
      
      def main():
          for _ in range(3):
              count()
      
      if __name__ == "__main__":
          s = time.perf_counter()
          main()
          elapsed = time.perf_counter() - s
          print(f"{__file__} executed in {elapsed:0.2f} seconds.")
      
      3 và/hoặc
      async def g():
          # Pause here and come back to g() when f() is ready
          r = await f()
          return r
      
      5.

    • Bất cứ điều gì được xác định với

      import asyncio
      
      @asyncio.coroutine
      def py34_coro():
          """Generator-based coroutine, older syntax"""
          yield from stuff()
      
      async def py35_coro():
          """Native coroutine, modern syntax"""
          await stuff()
      
      2 đều không được sử dụng
      #!/usr/bin/env python3
      # chained.py
      
      import asyncio
      import random
      import time
      
      async def part1(n: int) -> str:
          i = random.randint(0, 10)
          print(f"part1({n}) sleeping for {i} seconds.")
          await asyncio.sleep(i)
          result = f"result{n}-1"
          print(f"Returning part1({n}) == {result}.")
          return result
      
      async def part2(n: int, arg: str) -> str:
          i = random.randint(0, 10)
          print(f"part2{n, arg} sleeping for {i} seconds.")
          await asyncio.sleep(i)
          result = f"result{n}-2 derived from {arg}"
          print(f"Returning part2{n, arg} == {result}.")
          return result
      
      async def chain(n: int) -> None:
          start = time.perf_counter()
          p1 = await part1(n)
          p2 = await part2(n, p1)
          end = time.perf_counter() - start
          print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
      
      async def main(*args):
          await asyncio.gather(*(chain(n) for n in args))
      
      if __name__ == "__main__":
          import sys
          random.seed(444)
          args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
          start = time.perf_counter()
          asyncio.run(main(*args))
          end = time.perf_counter() - start
          print(f"Program finished in {end:0.2f} seconds.")
      
      9, sẽ tăng
      #!/usr/bin/env python3
      # countasync.py
      
      import asyncio
      
      async def count():
          print("One")
          await asyncio.sleep(1)
          print("Two")
      
      async def main():
          await asyncio.gather(count(), count(), count())
      
      if __name__ == "__main__":
          import time
          s = time.perf_counter()
          asyncio.run(main())
          elapsed = time.perf_counter() - s
          print(f"{__file__} executed in {elapsed:0.2f} seconds.")
      
      00.

  • Giống như nó là một

    #!/usr/bin/env python3
    # countasync.py
    
    import asyncio
    
    async def count():
        print("One")
        await asyncio.sleep(1)
        print("Two")
    
    async def main():
        await asyncio.gather(count(), count(), count())
    
    if __name__ == "__main__":
        import time
        s = time.perf_counter()
        asyncio.run(main())
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    00 để sử dụng
    #!/usr/bin/env python3
    # rand.py
    
    import asyncio
    import random
    
    # ANSI colors
    c = (
        "\033[0m",   # End of color
        "\033[36m",  # Cyan
        "\033[91m",  # Red
        "\033[35m",  # Magenta
    )
    
    async def makerandom(idx: int, threshold: int = 6) -> int:
        print(c[idx + 1] + f"Initiated makerandom({idx}).")
        i = random.randint(0, 10)
        while i <= threshold:
            print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
            await asyncio.sleep(idx + 1)
            i = random.randint(0, 10)
        print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
        return i
    
    async def main():
        res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
        return res
    
    if __name__ == "__main__":
        random.seed(444)
        r1, r2, r3 = asyncio.run(main())
        print()
        print(f"r1: {r1}, r2: {r2}, r3: {r3}")
    
    8 bên ngoài hàm
    async def g():
        # Pause here and come back to g() when f() is ready
        r = await f()
        return r
    
    7, đó là một
    #!/usr/bin/env python3
    # countasync.py
    
    import asyncio
    
    async def count():
        print("One")
        await asyncio.sleep(1)
        print("Two")
    
    async def main():
        await asyncio.gather(count(), count(), count())
    
    if __name__ == "__main__":
        import time
        s = time.perf_counter()
        asyncio.run(main())
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    00 để sử dụng
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 bên ngoài
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    2 Coroutine. Bạn chỉ có thể sử dụng
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 trong cơ thể của coroutines.

Dưới đây là một số ví dụ ngắn gọn nhằm tóm tắt các quy tắc trên:

async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y

Cuối cùng, khi bạn sử dụng

import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()
6, nó yêu cầu
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
0 là một đối tượng có thể chờ đợi. Chà, đó không phải là rất hữu ích, phải không? Hiện tại, chỉ cần biết rằng một đối tượng có thể chờ đợi là (1) một coroutine khác hoặc (2) một đối tượng xác định phương thức
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
10 Dunder trả về một trình lặp. Nếu bạn viết một chương trình, cho phần lớn các mục đích, bạn chỉ cần phải lo lắng về trường hợp số 1.

Điều đó đưa chúng ta đến một sự khác biệt kỹ thuật nữa mà bạn có thể thấy Pop Up: cách đánh dấu một chức năng như một coroutine là trang trí chức năng

async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
7 bình thường với
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
12. Kết quả là một coroutine dựa trên máy phát. Cấu trúc này đã bị lỗi thời kể từ khi cú pháp ____ 32/________ 33 được đưa vào vị trí trong Python 3.5.generator-based coroutine. This construction has been outdated since the
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2/
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 syntax was put in place in Python 3.5.

Hai coroutines này về cơ bản là tương đương (cả hai đều có thể chờ đợi), nhưng đầu tiên là dựa trên máy phát điện, trong khi thứ hai là một coroutine tự nhiên:generator-based, while the second is a native coroutine:

import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()

Nếu bạn tự viết bất kỳ mã nào, hãy thích các coroutines bản địa vì mục đích rõ ràng hơn là ẩn. Coroutines dựa trên máy phát điện sẽ bị loại bỏ trong Python 3.10.

Đối với nửa sau của hướng dẫn này, chúng tôi sẽ chạm vào các coroutines dựa trên máy phát điện để giải thích. Lý do mà ________ 32/________ 33 được giới thiệu là để biến coroutines thành một đặc điểm độc lập của python có thể dễ dàng phân biệt với hàm máy phát bình thường, do đó làm giảm sự mơ hồ.

Don Tiết bị sa lầy vào các coroutines dựa trên máy phát điện, đã bị cố tình lỗi thời bởi ____ 32/________ 33. Họ có bộ quy tắc nhỏ của riêng mình (ví dụ,

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 không thể được sử dụng trong coroutine dựa trên máy phát) phần lớn không liên quan nếu bạn dính vào cú pháp ________ 32/________ 33.

Không cần phải quảng cáo thêm, hãy để Lừa nhận thêm một vài ví dụ liên quan.

Dưới đây là một ví dụ về cách async IO cắt giảm thời gian chờ: đưa ra một coroutine

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
22 tiếp tục tạo ra các số nguyên ngẫu nhiên trong phạm vi [0, 10], cho đến khi một trong số chúng vượt quá ngưỡng, bạn muốn để nhiều cuộc gọi của coroutine này không cần Để chờ đợi nhau hoàn thành liên tiếp. Bạn có thể theo dõi phần lớn các mẫu từ hai tập lệnh ở trên, với những thay đổi nhỏ:

#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")

Đầu ra màu nói nhiều hơn tôi có thể và mang lại cho bạn ý nghĩa về cách thực hiện tập lệnh này:

Hướng dẫn why async await is used in python? - tại sao async đang chờ được sử dụng trong python?
Rand.py thực hiện

Chương trình này sử dụng một coroutine chính,

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
22 và chạy nó đồng thời qua 3 đầu vào khác nhau. Hầu hết các chương trình sẽ chứa các coroutines nhỏ, mô -đun và một chức năng trình bao bọc phục vụ để xâu chuỗi từng coroutines nhỏ hơn với nhau.
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 sau đó được sử dụng để thu thập các nhiệm vụ (tương lai) bằng cách lập bản đồ coroutine trung tâm trên một số nhóm có thể.

Trong ví dụ thu nhỏ này, nhóm là

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
25. Trong một ví dụ đầy đủ hơn được trình bày sau, đây là một tập hợp các URL cần được yêu cầu, phân tích cú pháp và xử lý đồng thời và
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 gói gọn toàn bộ thói quen đó cho mỗi URL.

Mặc dù việc tạo ra các số nguyên ngẫu nhiên, một số lượng lớn hơn (có thể không phải là lựa chọn lớn nhất với tư cách là ứng cử viên cho

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4, thì đó là sự hiện diện của
async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
2 trong ví dụ được thiết kế để bắt chước quy trình gắn IO, nơi không chắc chắn thời gian chờ đợi liên quan. Ví dụ: cuộc gọi
async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
2 có thể đại diện cho việc gửi và nhận số nguyên không ngẫu nhiên giữa hai máy khách trong một ứng dụng tin nhắn.

Các mẫu thiết kế IO không đồng bộ

Async IO đi kèm với tập hợp các thiết kế tập lệnh có thể, mà bạn sẽ được giới thiệu trong phần này.

Chuỗi coroutines

Một tính năng chính của coroutines là chúng có thể được xích lại với nhau. .

#!/usr/bin/env python3
# chained.py

import asyncio
import random
import time

async def part1(n: int) -> str:
    i = random.randint(0, 10)
    print(f"part1({n}) sleeping for {i} seconds.")
    await asyncio.sleep(i)
    result = f"result{n}-1"
    print(f"Returning part1({n}) == {result}.")
    return result

async def part2(n: int, arg: str) -> str:
    i = random.randint(0, 10)
    print(f"part2{n, arg} sleeping for {i} seconds.")
    await asyncio.sleep(i)
    result = f"result{n}-2 derived from {arg}"
    print(f"Returning part2{n, arg} == {result}.")
    return result

async def chain(n: int) -> None:
    start = time.perf_counter()
    p1 = await part1(n)
    p2 = await part2(n, p1)
    end = time.perf_counter() - start
    print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")

async def main(*args):
    await asyncio.gather(*(chain(n) for n in args))

if __name__ == "__main__":
    import sys
    random.seed(444)
    args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
    start = time.perf_counter()
    asyncio.run(main(*args))
    end = time.perf_counter() - start
    print(f"Program finished in {end:0.2f} seconds.")

Hãy chú ý cẩn thận đến đầu ra, trong đó

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
31 ngủ trong một khoảng thời gian thay đổi và
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
32 bắt đầu làm việc với kết quả khi chúng có sẵn:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
0

Trong thiết lập này, thời gian chạy của

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 sẽ bằng với thời gian chạy tối đa của các tác vụ mà nó tập hợp lại với nhau và lên lịch.

Sử dụng hàng đợi

Gói

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 cung cấp các lớp hàng đợi được thiết kế tương tự như các lớp của mô -đun
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
35. Trong các ví dụ của chúng tôi cho đến nay, chúng tôi đã thực sự có nhu cầu về cấu trúc hàng đợi. Trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
36, mỗi nhiệm vụ (tương lai) bao gồm một tập hợp các coroutines đang chờ đợi nhau rõ ràng và chuyển qua một đầu vào duy nhất trên mỗi chuỗi.

Có một cấu trúc thay thế cũng có thể hoạt động với Async IO: một số nhà sản xuất, không liên quan đến nhau, thêm các mặt hàng vào hàng đợi. Mỗi nhà sản xuất có thể thêm nhiều mặt hàng vào hàng đợi vào thời gian so le, ngẫu nhiên, không báo trước. Một nhóm người tiêu dùng kéo các mặt hàng từ hàng đợi khi họ xuất hiện, tham lam và không chờ đợi bất kỳ tín hiệu nào khác.

Trong thiết kế này, không có chuỗi người tiêu dùng cá nhân nào cho nhà sản xuất. Người tiêu dùng không biết số lượng nhà sản xuất, hoặc thậm chí số lượng các mặt hàng tích lũy sẽ được thêm vào hàng đợi, trước.

Nó cần một nhà sản xuất riêng lẻ hoặc người tiêu dùng một lượng thời gian thay đổi để đặt và trích xuất các mặt hàng từ hàng đợi, tương ứng. Hàng đợi phục vụ như một thông lượng có thể giao tiếp với các nhà sản xuất và người tiêu dùng mà không cần nói chuyện trực tiếp với nhau.

Phiên bản đồng bộ của chương trình này sẽ trông khá ảm đạm: một nhóm các nhà sản xuất chặn thêm các mặt hàng vào hàng đợi, một nhà sản xuất tại một thời điểm. Chỉ sau khi tất cả các nhà sản xuất được thực hiện, hàng đợi mới có thể được xử lý, bởi một người tiêu dùng tại một thời điểm xử lý từng mặt hàng. Có rất nhiều độ trễ trong thiết kế này. Các mặt hàng có thể ngồi yên trong hàng đợi thay vì được chọn và xử lý ngay lập tức.

Một phiên bản không đồng bộ,

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
37, bên dưới. Phần đầy thách thức của quy trình công việc này là cần phải có tín hiệu cho người tiêu dùng rằng sản xuất được thực hiện. Mặt khác,
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
38 sẽ treo vô thời hạn, vì hàng đợi sẽ được xử lý đầy đủ, nhưng người tiêu dùng đã giành được bất kỳ ý tưởng nào rằng sản xuất đã hoàn tất.

(Cảm ơn một số sự giúp đỡ từ người dùng StackOverflow vì đã giúp làm thẳng

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24: Điều quan trọng là
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
40, chặn cho đến khi tất cả các mục trong hàng đợi đã được nhận và xử lý, và sau đó hủy bỏ các nhiệm vụ của người tiêu dùng, nếu không sẽ bị treo lên và chờ đợi vô tận để các mục hàng đợi bổ sung xuất hiện.)

Đây là toàn bộ kịch bản:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
1

Một vài coroutines đầu tiên là các hàm trợ giúp trả về một chuỗi ngẫu nhiên, một bộ đếm hiệu suất thứ hai phân đoạn và một số nguyên ngẫu nhiên. Một nhà sản xuất đặt bất cứ nơi nào từ 1 đến 5 mặt hàng vào hàng đợi. Mỗi mục là một bộ giảm mạnh

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
41 trong đó
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
42 là một chuỗi ngẫu nhiên và
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
43 là thời gian mà nhà sản xuất cố gắng đặt tuple vào hàng đợi.

Khi một người tiêu dùng rút một mặt hàng ra, nó chỉ cần tính toán thời gian đã trôi qua mà mặt hàng ngồi trong hàng đợi bằng dấu thời gian mà vật phẩm được đưa vào.

Hãy nhớ rằng

async def f(x):
    y = await z(x)  # OK - `await` and `return` allowed in coroutines
    return y

async def g(x):
    yield x  # OK - this is an async generator

async def m(x):
    yield from gen(x)  # No - SyntaxError

def m(x):
    y = await z(x)  # Still no - SyntaxError (no `async def` here)
    return y
2 được sử dụng để bắt chước một số coroutine khác, phức tạp hơn sẽ ăn hết thời gian và chặn tất cả các thực thi khác nếu đó là một chức năng chặn thông thường.

Dưới đây là một thử nghiệm với hai nhà sản xuất và năm người tiêu dùng:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2

Trong trường hợp này, các mục xử lý theo phân số của một giây. Một sự chậm trễ có thể là do hai lý do:

  • Tiêu chuẩn, phần lớn không thể tránh khỏi
  • Tình huống mà tất cả người tiêu dùng đang ngủ khi một mặt hàng xuất hiện trong hàng đợi

Liên quan đến lý do thứ hai, may mắn thay, việc mở rộng quy mô lên hàng trăm hoặc hàng ngàn người tiêu dùng là hoàn toàn bình thường. Bạn không nên có vấn đề với

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
45. Vấn đề ở đây là, về mặt lý thuyết, bạn có thể có những người dùng khác nhau trên các hệ thống khác nhau kiểm soát việc quản lý nhà sản xuất và người tiêu dùng, với hàng đợi đóng vai trò là thông lượng trung tâm.

Cho đến nay, bạn đã bị ném ngay vào đám cháy và thấy ba ví dụ liên quan của

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 gọi các coroutines được xác định với
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2 và
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3. Nếu bạn không hoàn toàn theo dõi hoặc chỉ muốn đi sâu hơn vào các cơ chế về cách các coroutines hiện đại xuất hiện trong Python, bạn sẽ bắt đầu từ Square One với phần tiếp theo.

Rễ IO không đồng bộ trong máy phát điện

Trước đó, bạn đã thấy một ví dụ về các coroutines dựa trên kiểu máy tạo kiểu cũ, đã bị lỗi thời hơn bởi các coroutines bản địa rõ ràng hơn. Ví dụ đáng giá lại với một điều chỉnh nhỏ:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3

Như một thử nghiệm, điều gì xảy ra nếu bạn tự gọi

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
49 hoặc
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
50, không có
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 hoặc không có bất kỳ cuộc gọi nào đến
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52 hoặc các chức năng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 khác? Gọi một coroutine trong sự cô lập trả về một đối tượng coroutine:

>>>

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4

Điều này rất thú vị trên bề mặt của nó. Kết quả của việc tự gọi một coroutine là một đối tượng coroutine có thể chờ đợi.coroutine object.

Thời gian cho một bài kiểm tra: Tính năng nào khác của Python trông như thế này? .

Hy vọng rằng bạn sẽ nghĩ về các máy phát điện như một câu trả lời cho câu hỏi này, bởi vì các coroutines là các máy phát điện được tăng cường dưới mui xe. Hành vi tương tự về vấn đề này:generators as an answer to this question, because coroutines are enhanced generators under the hood. The behavior is similar in this regard:

>>>

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
5

Điều này rất thú vị trên bề mặt của nó. Kết quả của việc tự gọi một coroutine là một đối tượng coroutine có thể chờ đợi.

Thời gian cho một bài kiểm tra: Tính năng nào khác của Python trông như thế này? .

Hy vọng rằng bạn sẽ nghĩ về các máy phát điện như một câu trả lời cho câu hỏi này, bởi vì các coroutines là các máy phát điện được tăng cường dưới mui xe. Hành vi tương tự về vấn đề này:

>>>

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
6

Điều này rất thú vị trên bề mặt của nó. Kết quả của việc tự gọi một coroutine là một đối tượng coroutine có thể chờ đợi.

Thời gian cho một bài kiểm tra: Tính năng nào khác của Python trông như thế này? .

Có một tính năng thứ hai và ít được biết đến của các máy phát điện cũng có vấn đề. Bạn cũng có thể gửi một giá trị vào một trình tạo thông qua phương thức

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
70 của nó. Điều này cho phép các trình tạo (và coroutines) gọi (
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3) nhau mà không chặn. Tôi đã giành được bất kỳ điều gì nữa vào các loại hạt và bu lông của tính năng này, bởi vì nó chủ yếu là để thực hiện các coroutines đằng sau hậu trường, nhưng bạn không nên thực sự cần phải tự mình sử dụng trực tiếp.

Nếu bạn quan tâm đến việc khám phá thêm, bạn có thể bắt đầu tại PEP 342, nơi các coroutines được chính thức giới thiệu. Brett Cannon từ cách mà The Heck thực hiện Async-Sewait hoạt động trong Python cũng là một bài đọc tốt, cũng như bài viết của Pymotw trên

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4. Cuối cùng, có khóa học tò mò của David David Beazley trên các coroutines và đồng thời, đi sâu vào cơ chế mà Coroutines chạy.

Chúng ta hãy cố gắng ngưng tụ tất cả các bài viết trên thành một vài câu: có một cơ chế đặc biệt độc đáo mà các coroutines này thực sự được chạy. Kết quả của chúng là một thuộc tính của đối tượng ngoại lệ bị ném khi phương thức

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
70 của họ được gọi. Có một số chi tiết khác biệt cho tất cả những điều này, nhưng có lẽ nó đã giành được giúp bạn sử dụng phần này của ngôn ngữ trong thực tế, vì vậy hãy để Lừa tiếp tục.

Để gắn kết mọi thứ với nhau, đây là một số điểm chính về chủ đề của Coroutines với tư cách là máy phát điện:

  • Coroutines là các máy phát điện được sử dụng lại, tận dụng các đặc điểm của các phương thức máy phát.

  • Coroutines dựa trên máy phát cũ sử dụng

    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9 để chờ kết quả coroutine. Cú pháp Python hiện đại trong các coroutines bản địa chỉ đơn giản là thay thế
    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9 bằng
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 như là phương tiện chờ đợi kết quả coroutine.
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 tương tự như
    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9, và nó thường giúp nghĩ về nó như vậy.

  • Việc sử dụng

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 là một tín hiệu đánh dấu điểm ngắt. Nó cho phép một coroutine tạm thời đình chỉ thực thi và cho phép chương trình quay lại sau.

Các tính năng khác: import asyncio @asyncio.coroutine def py34_coro(): """Generator-based coroutine, older syntax""" yield from stuff() async def py35_coro(): """Native coroutine, modern syntax""" await stuff() 4 và Async Generators + Confensions

Cùng với đơn giản ____ 32/________ 33, Python cũng cho phép

import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()
4 lặp lại qua một trình lặp không đồng bộ. Mục đích của một trình lặp không đồng bộ là để nó có thể gọi mã không đồng bộ ở mỗi giai đoạn khi nó được lặp lại.asynchronous iterator. The purpose of an asynchronous iterator is for it to be able to call asynchronous code at each stage when it is iterated over.

Một phần mở rộng tự nhiên của khái niệm này là một máy phát không đồng bộ. Hãy nhớ lại rằng bạn có thể sử dụng

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3,
async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
5 hoặc
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 trong một coroutine bản địa. Sử dụng
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 trong một coroutine trở nên có thể trong Python 3.6 (thông qua PEP 525), trong đó giới thiệu các máy phát không đồng bộ với mục đích cho phép
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 và
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 được sử dụng trong cùng một cơ thể chức năng coroutine:asynchronous generator. Recall that you can use
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3,
async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
5, or
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 in a native coroutine. Using
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 within a coroutine became possible in Python 3.6 (via PEP 525), which introduced asynchronous generators with the purpose of allowing
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 and
#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8 to be used in the same coroutine function body:

>>>

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
7

Cuối cùng nhưng không kém phần quan trọng, Python cho phép hiểu không đồng bộ với

import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()
4. Giống như người anh em đồng bộ của nó, đây là phần lớn đường cú pháp:asynchronous comprehension with
import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()
4. Like its synchronous cousin, this is largely syntactic sugar:

>>>

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
8

Cuối cùng nhưng không kém phần quan trọng, Python cho phép hiểu không đồng bộ với

import asyncio

@asyncio.coroutine
def py34_coro():
    """Generator-based coroutine, older syntax"""
    yield from stuff()

async def py35_coro():
    """Native coroutine, modern syntax"""
    await stuff()
4. Giống như người anh em đồng bộ của nó, đây là phần lớn đường cú pháp:neither asynchronous generators nor comprehensions make the iteration concurrent. All that they do is provide the look-and-feel of their synchronous counterparts, but with the ability for the loop in question to give up control to the event loop for some other coroutine to run.

Đây là một sự khác biệt quan trọng: cả các máy phát không đồng bộ cũng như sự toàn diện không làm cho việc lặp lại đồng thời. Tất cả những gì họ làm là cung cấp cái nhìn và cảm giác của các đối tác đồng bộ của họ, nhưng với khả năng vòng lặp trong câu hỏi để từ bỏ quyền kiểm soát vòng lặp sự kiện cho một số coroutine khác chạy.

Nói cách khác, các bộ lặp không đồng bộ và các máy phát không đồng bộ không được thiết kế để ánh xạ đồng thời một số hàm qua một chuỗi hoặc trình lặp. Họ chỉ được thiết kế để cho phép coroutine kèm theo cho phép các nhiệm vụ khác thay đổi. Các tuyên bố import asyncio @asyncio.coroutine def py34_coro(): """Generator-based coroutine, older syntax""" yield from stuff() async def py35_coro(): """Native coroutine, modern syntax""" await stuff() 4 và import asyncio @asyncio.coroutine def py34_coro(): """Generator-based coroutine, older syntax""" yield from stuff() async def py35_coro(): """Native coroutine, modern syntax""" await stuff() 3 chỉ cần thiết ở mức độ sử dụng đơn giản #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 8 hoặc #!/usr/bin/env python3 # countasync.py import asyncio async def count(): print("One") await asyncio.sleep(1) print("Two") async def main(): await asyncio.gather(count(), count(), count()) if __name__ == "__main__": import time s = time.perf_counter() asyncio.run(main()) elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 94 sẽ phá vỡ bản chất của #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 3 trong coroutine. Sự khác biệt này giữa sự không đồng bộ và đồng thời là một quan trọng để nắm bắt.

Vòng lặp sự kiện và

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52

Bạn có thể nghĩ về một vòng lặp sự kiện như một vòng lặp

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
97 theo dõi các coroutines, lấy phản hồi về những gì mà Id Idle và tìm kiếm những thứ có thể được thực hiện trong lúc này. Nó có thể đánh thức một coroutine nhàn rỗi khi bất cứ điều gì Coroutine đang chờ đợi trở nên có sẵn.

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
9

Cho đến nay, toàn bộ quản lý của vòng lặp sự kiện đã được xử lý hoàn toàn bởi một cuộc gọi chức năng:

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52, được giới thiệu trong Python 3.7, chịu trách nhiệm lấy vòng lặp sự kiện, chạy các tác vụ cho đến khi chúng được đánh dấu là hoàn thành, và sau đó đóng vòng lặp sự kiện.

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
0

Có một cách dài hơn để quản lý vòng lặp sự kiện

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4, với
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
00. Mẫu điển hình trông như thế này:

Bạn có thể thấy

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
01 nổi xung quanh trong các ví dụ cũ hơn, nhưng trừ khi bạn có nhu cầu cụ thể để điều chỉnh kiểm soát đối với quản lý vòng lặp sự kiện,
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52 nên đủ cho hầu hết các chương trình.

Điều quan trọng hơn là hiểu một chút bên dưới bề mặt về cơ học của vòng lặp sự kiện. Dưới đây là một vài điểm đáng căng thẳng về vòng lặp sự kiện.

#1: Coroutines donith tự mình làm nhiều cho đến khi họ gắn liền với vòng lặp sự kiện. Coroutines don’t do much on their own until they are tied to the event loop.

Bạn đã thấy điểm này trước đây trong phần giải thích về máy phát điện, nhưng nó đáng để phục hồi. Nếu bạn có một coroutine chính đang chờ đợi người khác, chỉ cần gọi nó trong sự cô lập có rất ít tác dụng:

>>>

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
1

Hãy nhớ sử dụng

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52 để thực sự buộc thực hiện bằng cách lên lịch cho
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 Coroutine (đối tượng tương lai) để thực hiện trên vòng lặp sự kiện:

>>>

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
2

Hãy nhớ sử dụng

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52 để thực sự buộc thực hiện bằng cách lên lịch cho
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 Coroutine (đối tượng tương lai) để thực hiện trên vòng lặp sự kiện:

. By default, an async IO event loop runs in a single thread and on a single CPU core. Usually, running one single-threaded event loop in one CPU core is more than sufficient. It is also possible to run event loops across multiple cores. Check out this talk by John Reese for more, and be warned that your laptop may spontaneously combust.

#2: Theo mặc định, vòng lặp sự kiện IO Async chạy trong một luồng duy nhất và trên một lõi CPU duy nhất. Thông thường, chạy một vòng lặp sự kiện đơn trong một lõi CPU là quá đủ. Cũng có thể chạy các vòng lặp sự kiện trên nhiều lõi. Hãy xem bài nói chuyện này của John Reese để biết thêm, và được cảnh báo rằng máy tính xách tay của bạn có thể tự cháy một cách tự nhiên. Event loops are pluggable. That is, you could, if you really wanted, write your own event loop implementation and have it run tasks just the same. This is wonderfully demonstrated in the

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
12 package, which is an implementation of the event loop in Cython.

#3. Vòng lặp sự kiện có thể cắm được. Đó là, bạn có thể, nếu bạn thực sự muốn, hãy viết triển khai vòng lặp sự kiện của riêng bạn và để nó chạy các tác vụ giống nhau. Điều này được thể hiện tuyệt vời trong gói

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
12, đây là việc triển khai vòng lặp sự kiện ở Cython.

Đó là những gì có nghĩa là của thuật ngữ vòng lặp có thể cắm được: Bạn có thể sử dụng bất kỳ triển khai hoạt động nào của một vòng lặp sự kiện, không liên quan đến cấu trúc của chính các coroutines. Gói #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 4 tự vận chuyển với hai lần triển khai vòng lặp sự kiện khác nhau, với mặc định dựa trên mô -đun $ python3 countasync.py One One One Two Two Two countasync.py executed in 1.01 seconds. 14. (Việc triển khai thứ hai chỉ được xây dựng cho Windows.)

Một chương trình đầy đủ: Yêu cầu không đồng bộ

Bạn đã làm cho nó đến nay, và bây giờ là thời gian cho phần vui vẻ và không đau đớn. Trong phần này, bạn sẽ xây dựng một trình thu thập URL xẹp web,

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
15, sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
6, khung máy khách/máy chủ HTTP Async nhanh chóng rực rỡ. .

  1. Cấu trúc chương trình cấp cao sẽ trông như thế này:

  2. Đọc một chuỗi các URL từ một tệp cục bộ,

    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    17.

  3. Gửi nhận yêu cầu cho các URL và giải mã nội dung kết quả. Nếu điều này thất bại, hãy dừng lại ở đó cho một URL.

  4. Tìm kiếm các URL trong các thẻ

    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    18 trong HTML của các phản hồi.

  5. Viết kết quả vào

    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    19.

Làm tất cả những điều trên càng không đồng bộ và đồng thời càng tốt. .

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
3

Dưới đây là nội dung của

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
17. Nó không lớn, và chứa các trang web chủ yếu bị buôn bán:

URL thứ hai trong danh sách sẽ trả về phản hồi 404, mà bạn sẽ cần phải xử lý một cách duyên dáng. Nếu bạn đang chạy một phiên bản mở rộng của chương trình này, bạn có thể cần phải giải quyết nhiều vấn đề về tóc hơn thế này, một sự ngắt kết nối máy chủ như vậy và chuyển hướng vô tận.

Các yêu cầu nên được thực hiện bằng cách sử dụng một phiên duy nhất, để tận dụng việc sử dụng lại nhóm kết nối nội bộ phiên.

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
4

Hãy cùng xem chương trình đầy đủ. Chúng tôi sẽ đi qua mọi thứ từng bước sau:

Kịch bản này dài hơn các chương trình đồ chơi ban đầu của chúng tôi, vì vậy hãy để chúng phá vỡ nó.

>>>

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
5

Hãy nhớ sử dụng

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52 để thực sự buộc thực hiện bằng cách lên lịch cho
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 Coroutine (đối tượng tương lai) để thực hiện trên vòng lặp sự kiện:

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
6

.

#2: Theo mặc định, vòng lặp sự kiện IO Async chạy trong một luồng duy nhất và trên một lõi CPU duy nhất. Thông thường, chạy một vòng lặp sự kiện đơn trong một lõi CPU là quá đủ. Cũng có thể chạy các vòng lặp sự kiện trên nhiều lõi. Hãy xem bài nói chuyện này của John Reese để biết thêm, và được cảnh báo rằng máy tính xách tay của bạn có thể tự cháy một cách tự nhiên.

#3. Vòng lặp sự kiện có thể cắm được. Đó là, bạn có thể, nếu bạn thực sự muốn, hãy viết triển khai vòng lặp sự kiện của riêng bạn và để nó chạy các tác vụ giống nhau. Điều này được thể hiện tuyệt vời trong gói

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
12, đây là việc triển khai vòng lặp sự kiện ở Cython.

Phải thừa nhận rằng, phần thứ hai của

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
32 đang chặn, nhưng nó bao gồm một trận đấu regex nhanh và đảm bảo rằng các liên kết được phát hiện được thực hiện thành các đường dẫn tuyệt đối.

Trong trường hợp cụ thể này, mã đồng bộ này phải nhanh chóng và không rõ ràng. Nhưng chỉ cần nhớ rằng bất kỳ dòng nào trong một coroutine nhất định sẽ chặn các coroutines khác trừ khi dòng đó sử dụng

#!/usr/bin/env python3
# rand.py

import asyncio
import random

# ANSI colors
c = (
    "\033[0m",   # End of color
    "\033[36m",  # Cyan
    "\033[91m",  # Red
    "\033[35m",  # Magenta
)

async def makerandom(idx: int, threshold: int = 6) -> int:
    print(c[idx + 1] + f"Initiated makerandom({idx}).")
    i = random.randint(0, 10)
    while i <= threshold:
        print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
        await asyncio.sleep(idx + 1)
        i = random.randint(0, 10)
    print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
    return i

async def main():
    res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
    return res

if __name__ == "__main__":
    random.seed(444)
    r1, r2, r3 = asyncio.run(main())
    print()
    print(f"r1: {r1}, r2: {r2}, r3: {r3}")
8,
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 hoặc
async def g():
    # Pause here and come back to g() when f() is ready
    r = await f()
    return r
5. Nếu phân tích cú pháp là một quá trình chuyên sâu hơn, bạn có thể muốn xem xét việc chạy phần này trong quy trình riêng của nó với
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
39.

Tiếp theo, coroutine

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
40 lấy một đối tượng tệp và một URL duy nhất và chờ đợi trên
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
32 để trả về
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
42 của các URL được phân tích cú pháp, ghi từng loại vào tệp không đồng bộ cùng với URL nguồn của nó thông qua việc sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
7, một gói cho tệp không đồng bộ.

Cuối cùng,

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
44 đóng vai trò là điểm nhập chính vào chuỗi coroutines kịch bản. Nó sử dụng một phiên duy nhất và một tác vụ được tạo cho mỗi URL cuối cùng được đọc từ
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
17.

Dưới đây là một vài điểm bổ sung xứng đáng được đề cập:

  • Mặc định

    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    46 có bộ điều hợp với tối đa 100 kết nối mở. Để thay đổi điều đó, hãy chuyển một ví dụ
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    47 thành
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    46. Bạn cũng có thể chỉ định các giới hạn trên cơ sở mỗi người.

  • Bạn có thể chỉ định thời gian chờ tối đa cho cả phiên và cho các yêu cầu riêng lẻ.

  • Kịch bản này cũng sử dụng

    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    3, hoạt động với trình quản lý ngữ cảnh không đồng bộ. Tôi đã dành toàn bộ một phần cho khái niệm này bởi vì sự chuyển đổi từ các nhà quản lý bối cảnh đồng bộ sang không đồng bộ là khá đơn giản. Loại thứ hai phải xác định
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    50 và
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    51 thay vì
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    52 và
    $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    53. Như bạn có thể mong đợi,
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    3 chỉ có thể được sử dụng bên trong hàm coroutine được khai báo với
    import asyncio
    
    @asyncio.coroutine
    def py34_coro():
        """Generator-based coroutine, older syntax"""
        yield from stuff()
    
    async def py35_coro():
        """Native coroutine, modern syntax"""
        await stuff()
    
    2.

Nếu bạn muốn khám phá thêm một chút, các tệp đồng hành cho hướng dẫn này tại GitHub cũng có các bình luận và tài liệu được đính kèm.

Ở đây, việc thực hiện trong tất cả các vinh quang của nó, khi

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
15 nhận được, phân tích cú pháp và lưu kết quả cho 9 URL trong một giây:

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
7

Điều đó không quá tồi tàn! Khi kiểm tra Sanity, bạn có thể kiểm tra số lượng dòng trên đầu ra. Trong trường hợp của tôi, nó Lừa 626, mặc dù hãy nhớ rằng điều này có thể dao động:

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
8

Async io trong bối cảnh

Bây giờ, bạn đã thấy một liều mã lành mạnh, hãy để Lùi lại trong một phút và xem xét khi nào Async IO là một lựa chọn lý tưởng và làm thế nào bạn có thể so sánh để đưa ra kết luận đó hoặc chọn một mô hình đồng thời khác.

Async IO là khi nào và tại sao là lựa chọn đúng đắn?

Hướng dẫn này không phải là nơi cho một chuyên luận mở rộng về IO không đồng bộ so với luồng so với đa xử lý. Tuy nhiên, nó rất hữu ích khi có một ý tưởng về khi Async IO có lẽ là ứng cử viên tốt nhất trong ba người.

Trận chiến về IO Async so với đa xử lý không thực sự là một trận chiến. Trong thực tế, chúng có thể được sử dụng trong buổi hòa nhạc. Nếu bạn có nhiều nhiệm vụ liên kết CPU khá đồng đều (một ví dụ tuyệt vời là tìm kiếm lưới trong các thư viện như

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
57 hoặc
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
58), đa xử lý phải là một lựa chọn rõ ràng.

Đơn giản chỉ cần đặt

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
2 trước mọi chức năng là một ý tưởng tồi nếu tất cả các chức năng sử dụng các cuộc gọi chặn. .

Cuộc thi giữa Async IO và luồng là trực tiếp hơn một chút. Tôi đã đề cập trong phần giới thiệu rằng chủ đề của người Viking là khó khăn. Câu chuyện đầy đủ là, ngay cả trong trường hợp luồng có vẻ dễ thực hiện, nó vẫn có thể dẫn đến các lỗi không thể truy cập khét tiếng do điều kiện chủng tộc và sử dụng bộ nhớ, trong số những thứ khác.

Chủ đề cũng có xu hướng tỷ lệ ít thanh lịch hơn IO Async, bởi vì các luồng là một tài nguyên hệ thống có tính khả dụng hữu hạn. Tạo hàng ngàn luồng sẽ bị lỗi trên nhiều máy và tôi không khuyên bạn nên thử nó ngay từ đầu. Tạo ra hàng ngàn nhiệm vụ IO Async là hoàn toàn khả thi.

Async IO tỏa sáng khi bạn có nhiều nhiệm vụ ràng buộc IO trong đó các nhiệm vụ sẽ bị chi phối bằng cách chặn thời gian chờ đợi IO, chẳng hạn như:

  • Mạng IO, cho dù chương trình của bạn là máy chủ hay phía máy khách

  • Các thiết kế không có máy chủ, chẳng hạn như mạng ngang hàng, đa người dùng như phòng trò chuyện nhóm

  • Đọc/viết các hoạt động nơi bạn muốn bắt chước một phong cách lửa và lửa của người khác nhưng ít lo lắng về việc giữ một khóa trên bất cứ điều gì bạn đang đọc và viết thư

Lý do lớn nhất để không sử dụng nó là

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3 chỉ hỗ trợ một tập hợp các đối tượng cụ thể xác định một tập hợp các phương thức cụ thể. Nếu bạn muốn thực hiện các hoạt động đọc Async với một DBM nhất định, bạn sẽ không chỉ tìm thấy một trình bao bọc Python cho DBMS đó, mà còn hỗ trợ cú pháp ________ 32/________ 33. Các coroutines có chứa các cuộc gọi đồng bộ chặn các coroutines và nhiệm vụ khác chạy.

Để biết danh sách các thư viện hoạt động với ________ 32/________ 33, hãy xem danh sách ở cuối hướng dẫn này.

Nó là IO, nhưng cái nào?

Hướng dẫn này tập trung vào Async IO, cú pháp ____ 32/________ 33 và sử dụng

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 để quản lý vòng lặp sự kiện và chỉ định các nhiệm vụ.
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 Chắc chắn là thư viện IO Async duy nhất ngoài kia. Quan sát này từ Nathaniel J. Smith nói rất nhiều:

.

Điều mà tôi đã tranh luận, có hiệu lực, là

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 là nạn nhân của thành công của chính nó: khi nó được thiết kế, nó đã sử dụng phương pháp tốt nhất có thể; Nhưng kể từ đó, công việc lấy cảm hứng từ
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 - giống như việc bổ sung ________ 32/________ 33 - đã thay đổi cảnh quan để chúng ta có thể làm tốt hơn nữa, và bây giờ ____34 bị cản trở bởi các cam kết trước đó. (Nguồn)

Cuối cùng, một vài lựa chọn thay thế tên tuổi lớn làm những gì

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 làm, mặc dù với các API khác nhau và các cách tiếp cận khác nhau, là
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
77 và
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
78. Cá nhân, tôi nghĩ rằng nếu bạn xây dựng một chương trình đơn giản, có kích thước vừa phải, chỉ cần sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 là đủ và dễ hiểu, và cho phép bạn tránh thêm một sự phụ thuộc lớn khác bên ngoài thư viện tiêu chuẩn Python.

Nhưng bằng mọi cách, hãy xem

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
77 và
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
78, và bạn có thể thấy rằng họ nhận được điều tương tự được thực hiện theo cách mà trực quan hơn đối với bạn với tư cách là người dùng. Nhiều khái niệm không chính đáng của gói được trình bày ở đây cũng sẽ thấm vào các gói IO Async thay thế.

Vụn vặt

Trong một vài phần tiếp theo này, bạn sẽ bao gồm một số phần linh tinh của

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4 và ________ 32/________ 33 mà thiên đường phù hợp với hướng dẫn cho đến nay, nhưng vẫn rất quan trọng để xây dựng và hiểu một chương trình đầy đủ.

Các chức năng #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 4 cấp cao nhất khác

Ngoài

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52, bạn đã thấy một vài hàm cấp gói khác như
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
87 và
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
88.

Bạn có thể sử dụng

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
89 để lên lịch thực hiện đối tượng Coroutine, theo sau là
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52:

>>>

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
9

Có một sự tinh tế cho mô hình này: Nếu bạn không có

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91 trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24, nó có thể kết thúc trước khi
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 tự báo cáo rằng nó đã hoàn tất. Bởi vì
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
94 gọi
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
95, vòng lặp sự kiện chỉ được quan tâm (không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91) rằng
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện, không phải là các nhiệm vụ được tạo trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện. Không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91, các nhiệm vụ khác của Loop sẽ bị hủy, có thể trước khi chúng được hoàn thành. Nếu bạn cần có được một danh sách các nhiệm vụ hiện đang chờ xử lý, bạn có thể sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
00.

Một cách riêng biệt, có

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
88. Mặc dù nó không làm bất cứ điều gì đặc biệt rất đặc biệt,
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
02 có nghĩa là đặt một bộ sưu tập các coroutines (tương lai) vào một tương lai duy nhất. Do đó, nó trả về một đối tượng trong tương lai duy nhất và, nếu bạn
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
03 và chỉ định nhiều tác vụ hoặc coroutines, bạn đã chờ đợi tất cả chúng được hoàn thành. (Điều này hơi tương đương
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
04 từ ví dụ trước của chúng tôi.) Kết quả của
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
02 sẽ là danh sách các kết quả trên các đầu vào:

>>>

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
0

Có một sự tinh tế cho mô hình này: Nếu bạn không có

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91 trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24, nó có thể kết thúc trước khi
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 tự báo cáo rằng nó đã hoàn tất. Bởi vì
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
94 gọi
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
95, vòng lặp sự kiện chỉ được quan tâm (không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91) rằng
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện, không phải là các nhiệm vụ được tạo trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện. Không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91, các nhiệm vụ khác của Loop sẽ bị hủy, có thể trước khi chúng được hoàn thành. Nếu bạn cần có được một danh sách các nhiệm vụ hiện đang chờ xử lý, bạn có thể sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
00.

>>>

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
1

Có một sự tinh tế cho mô hình này: Nếu bạn không có

$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91 trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24, nó có thể kết thúc trước khi
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 tự báo cáo rằng nó đã hoàn tất. Bởi vì
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
94 gọi
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
95, vòng lặp sự kiện chỉ được quan tâm (không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91) rằng
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện, không phải là các nhiệm vụ được tạo trong
#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
24 được thực hiện. Không có
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
91, các nhiệm vụ khác của Loop sẽ bị hủy, có thể trước khi chúng được hoàn thành. Nếu bạn cần có được một danh sách các nhiệm vụ hiện đang chờ xử lý, bạn có thể sử dụng
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
00.

Một cách riêng biệt, có $ python3 countasync.py One One One Two Two Two countasync.py executed in 1.01 seconds. 88. Mặc dù nó không làm bất cứ điều gì đặc biệt rất đặc biệt, #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 02 có nghĩa là đặt một bộ sưu tập các coroutines (tương lai) vào một tương lai duy nhất. Do đó, nó trả về một đối tượng trong tương lai duy nhất và, nếu bạn #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 03 và chỉ định nhiều tác vụ hoặc coroutines, bạn đã chờ đợi tất cả chúng được hoàn thành. (Điều này hơi tương đương #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 04 từ ví dụ trước của chúng tôi.) Kết quả của #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 02 sẽ là danh sách các kết quả trên các đầu vào:

Bạn có thể nhận thấy rằng

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
02 chờ trên toàn bộ tập hợp kết quả của tương lai hoặc coroutines mà bạn vượt qua nó. Ngoài ra, bạn có thể lặp qua
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
07 để nhận nhiệm vụ khi chúng được hoàn thành, theo thứ tự hoàn thành. Hàm trả về một trình lặp lại mang lại các nhiệm vụ khi chúng hoàn thành. Dưới đây, kết quả của
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
08 sẽ có sẵn trước khi
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
09 hoàn tất, không phải là trường hợp với
#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
02:

Cuối cùng, bạn cũng có thể thấy #!/usr/bin/env python3 # countsync.py import time def count(): print("One") time.sleep(1) print("Two") def main(): for _ in range(3): count() if __name__ == "__main__": s = time.perf_counter() main() elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 11. Bạn hiếm khi cần nó, bởi vì nó là một API hệ thống ống nước cấp thấp hơn và phần lớn được thay thế bằng $ python3 countasync.py One One One Two Two Two countasync.py executed in 1.01 seconds. 89, được giới thiệu sau đó.

Ưu tiên của

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
3

  • Mặc dù họ hành xử có phần tương tự nhau, từ khóa

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 có quyền ưu tiên cao hơn đáng kể so với
    #!/usr/bin/env python3
    # rand.py
    
    import asyncio
    import random
    
    # ANSI colors
    c = (
        "\033[0m",   # End of color
        "\033[36m",  # Cyan
        "\033[91m",  # Red
        "\033[35m",  # Magenta
    )
    
    async def makerandom(idx: int, threshold: int = 6) -> int:
        print(c[idx + 1] + f"Initiated makerandom({idx}).")
        i = random.randint(0, 10)
        while i <= threshold:
            print(c[idx + 1] + f"makerandom({idx}) == {i} too low; retrying.")
            await asyncio.sleep(idx + 1)
            i = random.randint(0, 10)
        print(c[idx + 1] + f"---> Finished: makerandom({idx}) == {i}" + c[0])
        return i
    
    async def main():
        res = await asyncio.gather(*(makerandom(i, 10 - i - 1) for i in range(3)))
        return res
    
    if __name__ == "__main__":
        random.seed(444)
        r1, r2, r3 = asyncio.run(main())
        print()
        print(f"r1: {r1}, r2: {r2}, r3: {r3}")
    
    8. Điều này có nghĩa là, vì nó bị ràng buộc chặt chẽ hơn, có một số trường hợp mà bạn cần dấu ngoặc đơn trong một tuyên bố
    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9 không bắt buộc trong một tuyên bố tương tự ____33. Để biết thêm thông tin, hãy xem các ví dụ về các biểu thức
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 từ PEP 492.

  • Sự kết luận

  • Bây giờ bạn được trang bị để sử dụng ____ 32/________ 33 và các thư viện được xây dựng từ nó. Ở đây, một bản tóm tắt về những gì bạn đã đề cập:

Tài nguyên

Phiên bản Python Cụ thể cụ thể

Async IO trong Python đã phát triển nhanh chóng, và thật khó để theo dõi những gì đến khi. Dưới đây, một danh sách các thay đổi và giới thiệu phiên bản phụ Python liên quan đến

#!/usr/bin/env python3
# countsync.py

import time

def count():
    print("One")
    time.sleep(1)
    print("Two")

def main():
    for _ in range(3):
        count()

if __name__ == "__main__":
    s = time.perf_counter()
    main()
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
4:

  • 3.3: Biểu thức

    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9 cho phép ủy quyền máy phát.

  • 3.4:

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4 đã được giới thiệu trong thư viện tiêu chuẩn Python với trạng thái API tạm thời.

  • 3.5:

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    2 và
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 trở thành một phần của ngữ pháp Python, được sử dụng để biểu thị và chờ đợi trên các coroutines. Họ chưa được đặt trước từ khóa. (Bạn vẫn có thể xác định các hàm hoặc biến có tên
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    2 và
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3.)

  • 3.6: Các máy phát không đồng bộ và sự toàn diện không đồng bộ đã được giới thiệu. API của

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4 được tuyên bố ổn định hơn là tạm thời.

  • 3.7:

    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    2 và
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    3 trở thành từ khóa dành riêng. (Chúng không thể được sử dụng làm định danh.) Chúng được dự định thay thế bộ trang trí
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    34.
    #!/usr/bin/env python3
    # countasync.py
    
    import asyncio
    
    async def count():
        print("One")
        await asyncio.sleep(1)
        print("Two")
    
    async def main():
        await asyncio.gather(count(), count(), count())
    
    if __name__ == "__main__":
        import time
        s = time.perf_counter()
        asyncio.run(main())
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    52 đã được giới thiệu vào gói
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4, trong số một loạt các tính năng khác.

Nếu bạn muốn an toàn (và có thể sử dụng

#!/usr/bin/env python3
# countasync.py

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
52), hãy đi với Python 3.7 trở lên để có được toàn bộ các tính năng.

Bài viết

Ở đây, một danh sách quản lý các tài nguyên bổ sung:

  • Real Python: Tăng tốc chương trình Python của bạn với sự đồng thời
  • Real Python: Khóa thông dịch viên toàn cầu Python là gì?
  • CPYThon: Nguồn gói
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4
  • Tài liệu Python: Mô hình dữ liệu> Coroutines
  • Talkpython: Các kỹ thuật và ví dụ không đồng bộ trong Python
  • Brett Cannon: Làm thế nào mà Async-Sewait hoạt động trong Python 3.5?
  • PYMOTW:
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4
  • A. Jesse Jiryu Davis và Guido Van Rossum: Một trình thu thập thông tin web với Asyncio Coroutines
  • Andy Pearce: Bang Python Coroutines:
    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9
  • Nathaniel J. Smith: Một số suy nghĩ về thiết kế API không đồng bộ trong một bài viết -________ 32/________ 33 Thế giới
  • Armin Ronacher: Tôi không hiểu Python từ Asyncio
  • Andy Balaam: Sê -ri trên
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4 (4 bài viết)
  • Overflow Stack: Python
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    44 trong ________ 32 -________ 33 Chức năng
  • Yeray Diaz:
    • Asyncio cho nhà phát triển Python làm việc
    • Các mẫu Asyncio Coroutine: Beyond
      #!/usr/bin/env python3
      # countsync.py
      
      import time
      
      def count():
          print("One")
          time.sleep(1)
          print("Two")
      
      def main():
          for _ in range(3):
              count()
      
      if __name__ == "__main__":
          s = time.perf_counter()
          main()
          elapsed = time.perf_counter() - s
          print(f"{__file__} executed in {elapsed:0.2f} seconds.")
      
      3

Một vài python những gì mà các phần mới giải thích động lực đằng sau những thay đổi ngôn ngữ chi tiết hơn:

  • Những gì mới trong Python 3.3 (
    #!/usr/bin/env python3
    # chained.py
    
    import asyncio
    import random
    import time
    
    async def part1(n: int) -> str:
        i = random.randint(0, 10)
        print(f"part1({n}) sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-1"
        print(f"Returning part1({n}) == {result}.")
        return result
    
    async def part2(n: int, arg: str) -> str:
        i = random.randint(0, 10)
        print(f"part2{n, arg} sleeping for {i} seconds.")
        await asyncio.sleep(i)
        result = f"result{n}-2 derived from {arg}"
        print(f"Returning part2{n, arg} == {result}.")
        return result
    
    async def chain(n: int) -> None:
        start = time.perf_counter()
        p1 = await part1(n)
        p2 = await part2(n, p1)
        end = time.perf_counter() - start
        print(f"-->Chained result{n} => {p2} (took {end:0.2f} seconds).")
    
    async def main(*args):
        await asyncio.gather(*(chain(n) for n in args))
    
    if __name__ == "__main__":
        import sys
        random.seed(444)
        args = [1, 2, 3] if len(sys.argv) == 1 else map(int, sys.argv[1:])
        start = time.perf_counter()
        asyncio.run(main(*args))
        end = time.perf_counter() - start
        print(f"Program finished in {end:0.2f} seconds.")
    
    9 và PEP 380)
  • Những gì mới trong Python 3.6 (PEP 525 & 530)

Từ David Beazley:

  • Máy phát điện: Thủ thuật cho các lập trình viên hệ thống
  • Một khóa học tò mò về coroutines và đồng thời
  • Máy phát điện: biên giới cuối cùng

Các cuộc nói chuyện trên YouTube:

  • John Reese - Suy nghĩ bên ngoài Gil với Asyncio và Multiprocessing - Pycon 2018
  • Keynote David Beazley - Chủ đề quan tâm (Python Asyncio)
  • David Beazley - Đồng thời Python từ đầu: Sống! - Pycon 2015
  • Raymond Hettinger, Keynote về đồng thời, Pybay 2017
  • Suy nghĩ về đồng thời, Raymond Hettinger, nhà phát triển lõi Python
  • Miguel Grinberg Python không đồng bộ cho người mới bắt đầu PYCON 2017
  • Yury Selivanov Asyncawait và Asyncio trong Python 3 6 và Beyond Pycon 2017
  • Sợ hãi và chờ đợi trong Async: Một hành trình man rợ đến trung tâm của giấc mơ Coroutine
  • Async là gì, nó hoạt động như thế nào và khi nào tôi nên sử dụng nó? (PYCON APAC 2014)

Thư viện hoạt động với ________ 32/________ 33

Từ aio-libs:

  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    6: Khung máy khách/máy chủ HTTP không đồng bộ
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    52: Hỗ trợ Redis Async IO
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    53: Hỗ trợ IO PostgreSQL Async
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    54: acync io memcached client
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    55: Máy khách IO Kafka Async
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    56: Hỗ trợ IO Zeromq Async
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    57: Lập lịch công việc để quản lý các nhiệm vụ nền tảng
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    58: Bộ nhớ cache đơn giản cho Async IO

Từ Magicstack:

  • $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    12: Vòng lặp sự kiện IO Async cực nhanh
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    60: (cũng rất nhanh) Async PostgreSQL hỗ trợ

Từ các máy chủ khác:

  • $ python3 countasync.py
    One
    One
    One
    Two
    Two
    Two
    countasync.py executed in 1.01 seconds.
    
    78: thân thiện hơn
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4 dự định giới thiệu một thiết kế đơn giản hơn hoàn toàn
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    7: Tệp Async IO
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    64: Thư viện HTTP giống như Async yêu cầu
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    65: Hỗ trợ Redis Async IO
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    66: Tích hợp mô -đun
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    9 với
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    69: Máy khách IO MongoDB Async
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    70: Không đồng bộ hóa
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    4
  • #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    72: như
    #!/usr/bin/env python3
    # countsync.py
    
    import time
    
    def count():
        print("One")
        time.sleep(1)
        print("Two")
    
    def main():
        for _ in range(3):
            count()
    
    if __name__ == "__main__":
        s = time.perf_counter()
        main()
        elapsed = time.perf_counter() - s
        print(f"{__file__} executed in {elapsed:0.2f} seconds.")
    
    73, nhưng Async

Điểm của Async đang chờ đợi Python là gì?

Chúng thường được sử dụng cho các nhiệm vụ hợp tác và hành xử như máy phát điện Python. Hàm Async sử dụng từ khóa đang chờ đợi để biểu thị một coroutine. Khi sử dụng từ khóa đang chờ, Coroutines giải phóng luồng điều khiển trở lại vòng lặp sự kiện. Để chạy một coroutine, chúng ta cần lên lịch cho vòng lặp sự kiện.to denote a coroutine. When using the await keyword, coroutines release the flow of control back to the event loop. To run a coroutine, we need to schedule it on the event loop.

Tôi có nên sử dụng Async đang chờ đợi trong Python không?

Lý do chính để sử dụng async/chờ đợi là để cải thiện thông lượng của chương trình bằng cách giảm lượng thời gian nhàn rỗi khi thực hiện I/O.Các chương trình với toán tử này được sử dụng một cách ngầm định được gọi là vòng lặp sự kiện để tung hứng nhiều đường dẫn thực thi cùng một lúc.to improve a program's throughput by reducing the amount of idle time when performing I/O. Programs with this operator are implicitly using an abstraction called an event loop to juggle multiple execution paths at the same time.

Một lợi ích của việc sử dụng Async đang chờ đợi là gì?

Một lợi ích đáng kể của mẫu Async/Await bằng các ngôn ngữ hỗ trợ rằng mã không đồng bộ, không chặn có thể được viết, với chi phí tối thiểu và trông gần giống như mã chặn đồng bộ, đồng bộ.asynchronous, non-blocking code can be written, with minimal overhead, and looking almost like traditional synchronous, blocking code.

Khi nào tôi nên sử dụng Python đang chờ đợi?

Bạn phải sử dụng từ khóa đang chờ đợi khi và chỉ khi chức năng bạn gọi là một coroutine.Nếu các chức năng Async có liên quan, sẽ có một "vòng lặp sự kiện" phối hợp các chức năng ASYNC này.if and only if the function you are calling is a coroutine. If async functions are involved there should be an "event loop" which orchestrates these async functions.