Điểm async đang chờ python là gì?

Lập trình không đồng bộ đã đạt được rất nhiều sức hút trong vài năm qua và vì lý do chính đáng. Mặc dù nó có thể khó hơn kiểu tuyến tính truyền thống, nhưng nó cũng hiệu quả hơn nhiều

Ví dụ: thay vì đợi một yêu cầu HTTP kết thúc trước khi tiếp tục thực hiện, với các coroutine không đồng bộ của Python, bạn có thể gửi yêu cầu và thực hiện các công việc khác đang chờ trong hàng đợi trong khi chờ yêu cầu HTTP kết thúc. Có thể cần suy nghĩ thêm một chút để hiểu đúng logic, nhưng bạn sẽ có thể xử lý nhiều công việc hơn với ít tài nguyên hơn

Ngay cả khi đó, cú pháp và việc thực thi các hàm không đồng bộ trong các ngôn ngữ như Python thực sự không khó lắm. Bây giờ, JavaScript là một câu chuyện khác, nhưng Python dường như thực thi nó khá tốt

Tính không đồng bộ dường như là một lý do lớn tại sao Node. js rất phổ biến cho lập trình phía máy chủ. Phần lớn mã chúng tôi viết, đặc biệt là trong các ứng dụng IO nặng như trang web, phụ thuộc vào tài nguyên bên ngoài. Đây có thể là bất cứ thứ gì từ cuộc gọi cơ sở dữ liệu từ xa đến POST tới dịch vụ REST. Ngay khi bạn yêu cầu bất kỳ tài nguyên nào trong số này, mã của bạn sẽ chờ xung quanh mà không có gì để làm

Với lập trình không đồng bộ, bạn cho phép mã của mình xử lý các tác vụ khác trong khi chờ các tài nguyên khác này phản hồi

quân đoàn

Một hàm không đồng bộ trong Python thường được gọi là 'coroutine', đây chỉ là một hàm sử dụng từ khóa

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
9 hoặc một hàm được trang trí bằng
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
0. Một trong các chức năng dưới đây sẽ hoạt động như một quy trình đăng quang và có hiệu quả tương đương về loại

import asyncio

async def ping_server[ip]:
    pass

@asyncio.coroutine
def load_file[path]:
    pass

Đây là những hàm đặc biệt trả về các đối tượng coroutine khi được gọi. Nếu bạn đã quen thuộc với JavaScript Promises, thì bạn có thể coi đối tượng được trả về này gần giống như một Promise. Gọi một trong hai điều này không thực sự chạy chúng, nhưng thay vào đó, một đối tượng coroutine được trả về, sau đó có thể được chuyển đến vòng lặp sự kiện để được thực thi sau này

Trong trường hợp bạn cần xác định xem một hàm có phải là một coroutine hay không, thì

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
0 cung cấp phương thức
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
1 thực hiện chính xác điều này cho bạn. Hoặc, nếu bạn cần xác định xem đối tượng được trả về từ hàm có phải là đối tượng coroutine hay không, bạn có thể sử dụng
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
2 để thay thế

Năng suất từ

Có một vài cách để thực sự gọi một coroutine, một trong số đó là phương thức

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3. Điều này đã được giới thiệu trong Python 3. 3 và đã được cải thiện hơn nữa trong Python 3. 5 ở dạng
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
4 [mà chúng ta sẽ đề cập sau]

Biểu thức

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3 có thể được sử dụng như sau

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']

Như bạn có thể thấy,

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3 đang được sử dụng trong một chức năng được trang trí bằng
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
0. Nếu bạn thử và sử dụng
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3 bên ngoài chức năng này, thì bạn sẽ gặp lỗi từ Python như thế này

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
0

Để sử dụng cú pháp này, nó phải nằm trong một hàm khác [thường là với trình trang trí coroutine]

Không đồng bộ/chờ đợi

Cú pháp mới hơn và rõ ràng hơn là sử dụng các từ khóa

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
4. Được giới thiệu trong Python 3. 5,
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
9 được sử dụng để khai báo một chức năng như một coroutine, giống như những gì mà trình trang trí
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
0 thực hiện. Nó có thể được áp dụng cho hàm bằng cách đặt nó ở phía trước của định nghĩa

Để thực sự gọi hàm này, chúng tôi sử dụng

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
02, thay vì
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3, nhưng theo cách tương tự

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
4

Một lần nữa, giống như

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
3, bạn không thể sử dụng cái này bên ngoài một coroutine khác, nếu không bạn sẽ gặp lỗi cú pháp

Trong Python 3. 5, cả hai cách gọi coroutine đều được hỗ trợ, nhưng cách gọi

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
4 được coi là cú pháp chính

Chạy vòng lặp sự kiện

Không có nội dung coroutine nào tôi mô tả ở trên sẽ quan trọng [hoặc hoạt động] nếu bạn không biết cách bắt đầu và chạy một vòng lặp sự kiện. Vòng lặp sự kiện là điểm thực thi trung tâm cho các chức năng không đồng bộ, vì vậy khi bạn thực sự muốn thực thi coroutine, đây là thứ bạn sẽ sử dụng

Vòng lặp sự kiện cung cấp khá nhiều tính năng cho bạn

  • Đăng ký, thực hiện và hủy cuộc gọi bị trì hoãn [chức năng không đồng bộ]
  • Tạo vận chuyển máy khách và máy chủ để liên lạc
  • Tạo các quy trình con và vận chuyển để liên lạc với chương trình khác
  • Chức năng ủy quyền gọi đến một nhóm chủ đề

Hãy xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, tiêu chuẩn được ngành chấp nhận và bao gồm bảng gian lận. Dừng các lệnh Git trên Google và thực sự tìm hiểu nó

Mặc dù thực tế có khá nhiều cấu hình và loại vòng lặp sự kiện mà bạn có thể sử dụng, nhưng hầu hết các chương trình bạn viết sẽ chỉ cần sử dụng thứ gì đó như thế này để lên lịch cho một chức năng

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
7

Ba dòng cuối cùng là những gì chúng tôi quan tâm ở đây. Nó bắt đầu bằng cách nhận vòng lặp sự kiện mặc định [

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
06], lên lịch và chạy tác vụ không đồng bộ, sau đó đóng vòng lặp khi chạy xong vòng lặp

Hàm

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
07 thực sự đang chặn, vì vậy nó sẽ không trả về cho đến khi tất cả các phương thức không đồng bộ được thực hiện. Vì chúng tôi chỉ chạy cái này trên một luồng, nên không có cách nào nó có thể di chuyển về phía trước trong khi vòng lặp đang diễn ra

Bây giờ, bạn có thể nghĩ rằng điều này không hữu ích lắm vì cuối cùng chúng ta cũng chặn vòng lặp sự kiện [thay vì chỉ các lệnh gọi IO], nhưng hãy tưởng tượng gói toàn bộ chương trình của bạn trong một hàm không đồng bộ, sau đó sẽ cho phép bạn chạy nhiều lệnh không đồng bộ

Bạn thậm chí có thể ngắt vòng lặp sự kiện thành luồng riêng của nó, cho phép nó xử lý tất cả các yêu cầu IO dài trong khi luồng chính xử lý logic chương trình hoặc giao diện người dùng

Một ví dụ

Được rồi, vậy hãy xem một ví dụ lớn hơn một chút mà chúng ta thực sự có thể chạy. Đoạn mã sau là một chương trình không đồng bộ khá đơn giản, lấy JSON từ Reddit, phân tích cú pháp JSON và in ra các bài đăng hàng đầu trong ngày từ /r/python, /r/programming và /r/compsci

Phương thức đầu tiên được hiển thị,

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
08, được gọi bởi
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
09 và chỉ tạo một yêu cầu HTTP GET tới URL Reddit thích hợp. Khi điều này được gọi với
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
02, vòng lặp sự kiện sau đó có thể tiếp tục và phục vụ các coroutine khác trong khi chờ phản hồi HTTP quay lại. Sau khi thực hiện xong, JSON được trả về
import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
09, được phân tích cú pháp và được in ra

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
4

Mã này hơi khác so với mã mẫu mà chúng tôi đã trình bày trước đó. Để có nhiều coroutine chạy trên vòng lặp sự kiện, chúng tôi đang sử dụng

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
42 và sau đó chạy vòng lặp mãi mãi để xử lý mọi thứ

Để chạy cái này, trước tiên bạn cần cài đặt

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
43, bạn có thể làm điều này với PIP

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
7

Bây giờ chỉ cần chắc chắn rằng bạn chạy nó với Python 3. 5 trở lên, và bạn sẽ nhận được kết quả như thế này

import asyncio

@asyncio.coroutine
def get_json[client, url]:
    file_content = yield from load_file['/Users/scott/data.txt']
8

Lưu ý rằng nếu bạn chạy điều này một vài lần, thứ tự in dữ liệu subreddit sẽ thay đổi. Điều này là do mỗi lệnh gọi chúng tôi thực hiện kiểm soát [lợi nhuận] của luồng, cho phép một lệnh gọi HTTP khác xử lý. Cái nào về trước in ra trước

Phần kết luận

Mặc dù chức năng không đồng bộ tích hợp sẵn của Python không mượt mà như JavaScript, nhưng điều đó không có nghĩa là bạn không thể sử dụng nó cho các ứng dụng thú vị và hiệu quả. Chỉ cần dành 30 phút để tìm hiểu thông tin chi tiết và bạn sẽ hiểu rõ hơn nhiều về cách bạn có thể tích hợp điều này vào các ứng dụng của riêng mình

Bạn nghĩ gì về async/await của Python?

Tại sao nên sử dụng async đang chờ trong Python?

Từ khóa không đồng bộ/đang chờ . Từ khóa async được sử dụng để tạo một coroutine Python. Từ khóa chờ tạm dừng việc thực thi một coroutine cho đến khi nó hoàn thành và trả về dữ liệu kết quả. Các từ khóa chờ đợi chỉ hoạt động trong chức năng không đồng bộ. simplify asynchronous programming in Python. The async keyword is used to create a Python coroutine. The await keyword suspends execution of a coroutine until it completes and returns the result data. The await keywords only works within an async function.

Điểm không đồng bộ đang chờ là gì?

Ghi chú. Mục đích của async / await là để đơn giản hóa cú pháp cần thiết để sử dụng các API dựa trên lời hứa . Hành vi của async/await tương tự như việc kết hợp các trình tạo và lời hứa. Các chức năng không đồng bộ luôn trả lại một lời hứa.

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

Các công cụ sửa đổi không đồng bộ và đang chờ của NET framework làm cho việc chuyển đổi mã của bạn từ lập trình đồng bộ sang lập trình không đồng bộ trở nên đơn giản và dễ dàng . Do đó, bạn có thể gọi một phương thức không đồng bộ một cách độc lập bằng cách truyền cho nó một đối tượng tác vụ, sau đó thực hiện một số công việc không liên quan, sau đó chờ tác vụ đó để xem liệu nó đã hoàn thành chưa.

Điều gì xảy ra nếu bạn không chờ một phương thức không đồng bộ Python?

Nó sẽ bị kẹt .

Chủ Đề