Chức năng không đồng bộ Python

Trong Phòng của Nhà văn tuần này - một loạt blog thường xuyên gồm các bài báo và hướng dẫn được viết bởi các nhà công nghệ trong Cộng đồng Andela của chúng tôi - Ezzeddin Abdullah giới thiệu về lập trình không đồng bộ trong Python bằng Async IO

Viết mã tuần tự [hoặc đồng bộ] quen thuộc với nhiều lập trình viên, ngay cả khi họ mới bắt đầu. Đó là loại mã được thực thi từng dòng một, từng lệnh một

Trong thế giới không đồng bộ, sự xuất hiện của các sự kiện độc lập với luồng chương trình chính. Điều này có nghĩa là các hành động được thực thi trong nền mà không cần chờ hoàn thành hành động trước đó

Nói cách khác, các dòng mã được thực hiện đồng thời

Hãy tưởng tượng bạn có một số nhiệm vụ độc lập nhất định và mỗi nhiệm vụ mất rất nhiều thời gian để hoàn thành. Đầu ra của chúng không phụ thuộc vào nhau. Vì vậy, bạn muốn bắt đầu tất cả chúng cùng một lúc. Nếu các tác vụ này được thực hiện theo một thứ tự cụ thể, chương trình sẽ phải đợi mỗi tác vụ hoàn thành trước khi bắt đầu tác vụ tiếp theo. Thời gian chờ đợi này đang chặn chương trình

Mô hình lập trình không đồng bộ giúp thực hiện đồng thời các tác vụ này và đảm bảo bạn có thể đánh bại thời gian chờ đợi đó và sử dụng tài nguyên hiệu quả hơn

Python 3 có hỗ trợ riêng cho lập trình không đồng bộ, Async IO, cung cấp một cách đơn giản để thực thi các tác vụ đồng thời

Đầu tiên, hãy thiết lập môi trường của chúng ta và bắt đầu

Thiết lập môi trường

Trong hướng dẫn này, chúng tôi sẽ sử dụng mô-đun async io trong Python 3. 7 trở lên, vì vậy chúng ta cần tạo một Python 3 mới. 7 môi trường. Một cách Python rõ ràng là thiết lập một môi trường ảo với conda và sau đó kích hoạt nó bằng các lệnh sau

Khối xây dựng lập trình không đồng bộ

Có 3 khối xây dựng chính của lập trình không đồng bộ Python

  1. Nhiệm vụ chính là vòng lặp sự kiện, chịu trách nhiệm quản lý các tác vụ không đồng bộ và phân phối chúng để thực thi
  2. Coroutines là các chức năng lên lịch thực hiện các sự kiện
  3. Hợp đồng tương lai là kết quả của việc thực hiện coroutine. Kết quả này có thể là một ngoại lệ

Giới thiệu async trong Python

Hai thành phần chính được giới thiệu trong Python

  1. async io là gói Python cho phép API chạy và quản lý coroutine
  2. async/await để giúp bạn xác định coroutines

Chức năng và hành vi của mã sẽ khác khi bạn chọn không đồng bộ hoặc đồng bộ hóa để thiết kế mã của mình

Nói rõ hơn, để thực hiện cuộc gọi HTTP, hãy cân nhắc sử dụng aiohttp , đây là gói Python cho phép bạn thực hiện cuộc gọi HTTP không đồng bộ. Nó có thể là một công cụ cần thiết nếu bạn bị chặn vì thư viện requests

Tương tự, nếu bạn đang làm việc với trình điều khiển Mongo, thay vì dựa vào trình điều khiển đồng bộ như mongo-python, bạn phải sử dụng trình điều khiển không đồng bộ như moto để truy cập MongoDB không đồng bộ

Trong thế giới không đồng bộ, mọi thứ chạy trong một vòng lặp sự kiện. Điều này cho phép bạn chạy một số coroutine cùng một lúc. Chúng ta sẽ xem coroutine là gì trong hướng dẫn này

Mọi thứ bên trong async def là mã không đồng bộ và mọi thứ khác là đồng bộ

Viết mã không đồng bộ không dễ như viết mã đồng bộ. Mô hình không đồng bộ Python dựa trên các khái niệm như sự kiện, gọi lại, vận chuyển, giao thức và tương lai

Mọi thứ diễn ra nhanh chóng trong thế giới không đồng bộ của Python, vì vậy hãy theo dõi các bản cập nhật mới nhất

Cách thức hoạt động của asyncio

Gói asyncio cung cấp hai khóa, asyncawait

Hãy xem ví dụ về thế giới xin chào async này

Thoạt nhìn, bạn có thể nghĩ rằng đây là mã đồng bộ vì bản in thứ hai đang đợi 1 giây để in “Xin chào lần nữa. ” sau “Xin chào thế giới. ”. Nhưng mã này thực sự không đồng bộ

quân đoàn

Bất kỳ hàm nào được định nghĩa là async def đều là một coroutine như async/await2 ở trên. Lưu ý rằng việc gọi hàm async/await2 không giống như gói nó bên trong hàm async/await4

Để chạy coroutine, asyncio cung cấp ba cơ chế chính

Hàm async/await4 là điểm vào chính của thế giới không đồng bộ bắt đầu vòng lặp sự kiện và chạy coroutine

async/await6 kết quả của quy trình đăng quang và chuyển điều khiển đến vòng lặp sự kiện

Đoạn mã trước vẫn đợi quy trình đăng ký async/await7 kết thúc nên nó thực thi tác vụ 1 trong 1 giây và sau đó thực hiện tác vụ thứ hai sau khi đợi 2 giây

Để coroutine chạy đồng thời ta nên tạo task, đây là cơ chế thứ 3

  1. Hàm async/await8 được sử dụng để lên lịch cho coroutine thực thi

Đoạn mã trên hiện đang chạy đồng thời và quy trình đăng ký async/await7 không còn chờ quy trình đăng ký async/await7 kết thúc. Thay vì chạy cùng một quy trình với các tham số khác nhau đồng thời

Điều gì xảy ra như sau

Quy trình say_something[] bắt đầu với tác vụ đầu tiên của tham số [1 giây và một chuỗi “Nhiệm vụ 1”]. Nhiệm vụ này được gọi là aiohttp1

Sau đó, nó tạm dừng việc thực thi quy trình đăng ký và đợi 1 giây để quy trình đăng ký async/await7 kết thúc khi nó gặp từ khóa đang chờ. Nó trả về điều khiển cho vòng lặp sự kiện


Tương tự đối với tác vụ thứ hai, nó tạm dừng việc thực thi quy trình đăng ký và đợi 2 giây để quy trình đăng ký async/await7 kết thúc khi gặp từ khóa đang chờ


Sau khi điều khiển aiohttp1 trở lại vòng lặp sự kiện, vòng lặp sự kiện tiếp tục nhiệm vụ thứ hai [ aiohttp5 ] vì aiohttp6 vẫn chưa kết thúc


Hàm async/await8 bao bọc hàm async/await7 và làm cho nó chạy coroutine đồng thời như một tác vụ không đồng bộ. Như bạn có thể thấy, đoạn mã trên cho thấy nó chạy nhanh hơn trước 1 giây

Coroutine được lên lịch tự động để chạy trong vòng lặp sự kiện khi async/await8 được gọi

Các tác vụ giúp bạn chạy đồng thời nhiều coroutine, nhưng đây không phải là cách duy nhất để đạt được đồng thời

Chạy các tác vụ đồng thời với asyncio. tập trung[]

Một cách khác để chạy đồng thời nhiều coroutine là sử dụng hàm requests0. Hàm này lấy các coroutine làm đối số và chạy chúng đồng thời

Trong đoạn mã trước, thủ tục chúc mừng[] được thực hiện đồng thời hai lần

đối tượng chờ đợi

Một đối tượng được gọi là có thể chờ nếu nó có thể được sử dụng với từ khóa đang chờ. Có 3 loại đối tượng chờ đợi chính. quy trình, nhiệm vụ và tương lai

quân đoàn

Trong ví dụ trước, các hàm quy trình requests1 và requests2 được chờ đợi bởi quy trình quy trình requests3

Giả sử bạn bỏ qua từ khóa đang chờ trước nhiều quy trình đăng ký. Sau đó, bạn sẽ nhận được lỗi sau. requests4 không bao giờ được chờ đợi

nhiệm vụ

Để lên lịch cho một coroutine chạy trong vòng lặp sự kiện, chúng ta sử dụng hàm async/await8

tương lai

Một requests6 là một đối tượng có thể chờ ở mức độ thấp đại diện cho kết quả của một phép tính không đồng bộ. Nó được tạo bằng cách gọi hàm requests7

Hết giờ

Sử dụng requests8 để đặt thời gian chờ cho một đối tượng có thể chờ hoàn thành. Lưu ý rằng requests9 ở đây là đối tượng chờ đợi. Điều này hữu ích nếu bạn muốn đưa ra một ngoại lệ nếu đối tượng chờ đợi mất quá nhiều thời gian để hoàn thành. Ngoại lệ như mongo-python0

Thời gian chờ ở đây trong đối tượng requests6 được đặt thành 1 giây mặc dù quy trình đăng ký mongo-python2 mất 400 giây để hoàn thành

suy nghĩ cuối cùng

Trong hướng dẫn này, chúng tôi đã giới thiệu lập trình không đồng bộ trong Python với mô-đun tích hợp Async IO. Chúng tôi đã xác định quy trình, nhiệm vụ và tương lai là gì

Chúng tôi cũng đề cập đến cách chạy nhiều coroutine đồng thời theo nhiều cách khác nhau và xem cách mã đồng thời có thể là lựa chọn tốt nhất của bạn khi bạn cần tối ưu hóa hiệu suất cho một số tác vụ nhất định

Bạn muốn trở thành một phần của Cộng đồng Andela?

Với hơn 175.000 nhà công nghệ trong cộng đồng của chúng tôi, tại hơn 90 quốc gia, chúng tôi cam kết tạo ra các nhóm kỹ thuật từ xa đa dạng với những tài năng hàng đầu thế giới. Và các thành viên trong mạng lưới của chúng tôi thích trở thành một phần của cộng đồng tài năng, thông qua các hoạt động, lợi ích, sự cộng tác cũng như các cuộc gặp gỡ trực tuyến và ảo

Python có async đang chờ không?

Từ khóa async/await đã được chuẩn hóa trong Python 3. 7 . Họ đơn giản hóa lập trình không đồng bộ trong Python. 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ả.

Tại sao nên sử dụng async trong Python?

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

Không đồng bộ có nhanh hơn đồng bộ hóa Python không?

Async không bị chặn, có nghĩa là nó sẽ gửi nhiều yêu cầu đến một máy chủ. Đồng bộ hóa đang chặn — nó sẽ chỉ gửi cho máy chủ một yêu cầu tại một thời điểm và sẽ đợi máy chủ trả lời yêu cầu đó. Async tăng thông lượng vì có thể chạy nhiều thao tác cùng lúc .

Chức năng không đồng bộ là gì?

Một hàm async sẽ trả về một tham chiếu khác , trong khi Promise. giải quyết trả về cùng một tham chiếu nếu giá trị đã cho là một lời hứa. Nó có thể là một vấn đề khi bạn muốn kiểm tra tính bằng nhau của một lời hứa và giá trị trả về của một hàm không đồng bộ.

Chủ Đề