Đối với công việc tư vấn mà tôi đã làm, tôi đã sử dụng python asyncio và hiểu được khó khăn trong cú pháp đơn giản của nó. Phải mất khá nhiều thời gian để đọc blog và các ví dụ để hiểu cách thức hoạt động của nó. Chủ đề này áp đảo vì lịch sử của nó với các trình tạo / cú pháp coroutine cũ hơn và yêu cầu một số kiến thức cơ bản về một số khái niệm để hiểu rõ hơn
Tôi muốn chia sẻ những điều mình học được, điều này sẽ giúp hiểu được các nguyên tắc cơ bản cốt lõi với các định nghĩa ngắn gọn và các ví dụ mã đơn giản để giúp làm việc với asyncio dễ dàng hơn. . ]
chủ đề
1] Giới thiệu
2] Lịch sử & Cách thức hoạt động
3] Tóm tắt
4] API HTTP đơn giản
Sau đây là tổng quan ngắn gọn về các thuật ngữ được sử dụng trong các chủ đề
Đồng thời vs Song song
- Đồng thời — khả năng thực thi hai hoặc nhiều tác vụ có thể bắt đầu, chạy và hoàn thành trong các khoảng thời gian chồng chéo [có thể là thực thi song song thực sự trên đa lõi hoặc cắt thời gian trên một máy lõi đơn với sự trợ giúp của các luồng]
- Tính song song —là về việc thực hiện các tác vụ song song cùng một lúc. [e. g. , ít nhất hai luồng đang thực thi đồng thời]
- Chủ đề - Chủ đề giúp thực thi nhiều tác vụ giúp đạt được Đồng thời/Song song. Trong một quy trình python duy nhất, không thể xử lý song song luồng do Khóa phiên dịch toàn cầu [triển khai CPython]. GIL là một cơ chế mutex ngăn nhiều luồng thực thi đồng thời trên các đối tượng Python. Vì vậy, chỉ một luồng có thể thực thi tại một thời điểm trong số nhiều luồng trong quy trình python
- Đa quy trình — Cần có nhiều quy trình python để đạt được tính song song. gói đa xử lý cung cấp cả đồng thời cục bộ và từ xa, hỗ trợ GIL một cách hiệu quả bằng cách sử dụng các quy trình con thay vì các luồng
Đồng bộ hóa và không đồng bộ
Đồng bộ hóa/Không đồng bộ là về cách tính toán/tác vụ được thực hiện trong ngữ cảnh của một Chủ đề duy nhất
- Đồng bộ hóa — chặn thực thi tác vụ. Việc thực thi tính toán/tác vụ bởi một Chủ đề [cpu] bị chặn/đang chờ một thao tác [IO] hoàn thành.
e. g. một luồng duy nhất xử lý yêu cầu http thực hiện cuộc gọi DB và đợi phản hồi db trả về phản hồi http, sau đó nhận yêu cầu http tiếp theo. - Không đồng bộ — thực hiện đồng thời các tác vụ. Nhiều tác vụ có thể bắt đầu, tạm dừng và hoàn thành độc lập với nhau được thực hiện bởi một luồng duy nhất. Các tác vụ không đồng bộ không chặn các hoạt động thường chờ IO. Nó chủ yếu hữu ích cho các trường hợp sử dụng liên kết IO [đĩa/mạng] vì CPU có thể được sử dụng cho các mục đích khác trong khi chúng tôi đang chờ IO. coroutines trong python giúp đạt được điều này.
e. g. một luồng xử lý yêu cầu http thực hiện cuộc gọi DB và tạm dừng tác vụ hiện tại cho phản hồi DB. Cùng một chủ đề nhận một yêu cầu mới và bắt đầu xử lý.
vòng lặp
Trình lặp là các đối tượng có thể được lặp lại [sử dụng __iter__ và __next__] một cách lười biếng
list = [1, 2]
iterator = iter[list]
print[next[iterator]]
print[iterator.__next__[]]
print[next[iterator]]# Output:
1
2
Raise StopIteration exception since no items to iterate
máy phát điện
Trình tạo [Thông thường] là các trình lặp giúp đơn giản hóa sự phức tạp trong việc xây dựng trình lặp logic tùy chỉnh. Nó tạo ra một giá trị nhanh chóng cho mỗi lần chạy [ví dụ:. , nhà sản xuất lười biếng]
Làm thế nào để tạo ra ?
trình tạo là bất kỳ chức năng bình thường nào với câu lệnh
import randomdef simple_generator[]:9 thay vì câu lệnh
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
def magic_pot[start=1, end=1000]:0
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
import randomdef simple_generator[]:9 là một từ khóa được sử dụng giống như
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stoppeddef magic_pot[start=1, end=1000]:0, ngoại trừ hàm sẽ trả về một trình tạo. Câu lệnh
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...import randomdef simple_generator[]:9 tạm dừng chức năng lưu tất cả các trạng thái của nó và sau đó tiếp tục từ trạng thái cuối cùng trong các lệnh gọi liên tiếp [tham khảo thêm tại đây]
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
import randomdef simple_generator[]:
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Đối tượng trình tạo ví dụ tương tự có thể được tương tác với vòng lặp 'for' vì nó là một trình vòng lặp
def magic_pot[start=1, end=1000]:
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
Chúng ta có thể tạo đường ống dẫn tương tự như đường ống Unix
________số 8PEP-380, [
def magic_pot[start=1, end=1000]:4 được giới thiệu để đơn giản hóa đường ống của máy phát điện]
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
- Bổ sung
def magic_pot[start=1, end=1000]:
5 trong Python 3. 3 giúp tái cấu trúc các trình tạo cũng như xâu chuỗi chúng lại với nhau dễ dàng hơn
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
import randomdef simple_generator[]:1
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
quy trình
Coroutines là các thành phần chương trình máy tính tổng quát hóa các chương trình con cho đa nhiệm không ưu tiên, bằng cách cho phép nhiều điểm vào để tạm dừng và tiếp tục thực thi tại các vị trí nhất định
Coroutines giúp đạt được đa nhiệm/đồng thời hợp tác. Chúng là các chức năng/tác vụ giúp thực thi đồng thời bằng cách có khả năng tạm dừng và tiếp tục các tác vụ trong một luồng. [e. g. , I/O không đồng bộ và các dạng lập trình hướng sự kiện hoặc đa nhiệm hợp tác khác]
Phát triển thành “Generator Coroutine”
Trình tạo không có khả năng chấp nhận các đối số trong khi thực thi, điều này khiến cho việc kiểm soát luồng logic bên trong hàm trình tạo trở nên khó khăn [e. g. một coroutine A chờ phản hồi từ một cuộc gọi http khác coroutine B. Coroutine A tạm dừng -> Coroutine B Http Complete -> Tiếp tục Coroutine A [phản hồi http từ Coroutine B]]
Trình tạo đã được phát triển để hỗ trợ các coroutine như khả năng sử dụng PEP-342 [Python 2. 5], giúp truyền tham số cho trình tạo để kiểm soát luồng thực thi. Điều này cuối cùng đã giúp đạt được các khả năng của coroutine, các hình thức đa nhiệm hợp tác khác
PEP-342
Các hàm tạo của Python gần như là các coroutines — nhưng không hoàn toàn — ở chỗ chúng cho phép tạm dừng thực thi để tạo ra một giá trị, nhưng không cung cấp các giá trị hoặc ngoại lệ được chuyển vào khi tiếp tục thực thi
bộ tạo không thể tạo ra quyền kiểm soát trong khi các chức năng khác đang thực thi, trừ khi các chức năng đó được thể hiện dưới dạng bộ tạo và bộ tạo bên ngoài được viết để tạo ra để đáp ứng các giá trị do bộ tạo bên trong tạo ra. Điều này làm phức tạp việc triển khai các trường hợp sử dụng thậm chí tương đối đơn giản như truyền thông không đồng bộ, bởi vì việc gọi bất kỳ chức năng nào cũng yêu cầu trình tạo chặn [i. e. không thể mang lại quyền kiểm soát], nếu không, phải thêm rất nhiều mã vòng lặp soạn sẵn xung quanh mỗi lệnh gọi hàm cần thiết
Tuy nhiên, nếu có thể chuyển các giá trị[send[]] hoặc ngoại lệ vào một trình tạo tại điểm mà nó bị treo, thì một bộ lập lịch đồng quy trình đơn giản hoặc chức năng tấm bạt lò xo sẽ cho phép các coroutine gọi lẫn nhau mà không bị chặn — một lợi ích to lớn cho tính năng không đồng bộ . Các ứng dụng như vậy sau đó có thể viết các đồng quy trình để thực hiện I/O ổ cắm không chặn bằng cách nhường quyền kiểm soát cho bộ lập lịch I/O cho đến khi dữ liệu được gửi hoặc có sẵn. Trong khi đó, mã thực hiện I/O sẽ đơn giản làm điều gì đó như thế này
dữ liệu = [lợi nhuận nonblocking_read[my_socket, nbytes]]
để tạm dừng thực thi cho đến khi nonblocking_read[] coroutine tạo ra một giá trị
Ở trên PEP đã thêm các cải tiến để thêm phương thức gửi [], ném [], đóng [] cho trình tạo.
import randomdef simple_generator[]:9 đã được thay đổi dưới dạng biểu thức và hoạt động như một công cụ giao tiếp hai chiều được giải thích trong ví dụ bên dưới
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
import randomdef simple_generator[]:3
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Coroutine vs Máy phát điện
Coroutine là một trình tạo tuân theo các quy ước nhất định
- coroutine nhường quyền kiểm soát cho một coroutine khác và có thể tiếp tục thực thi từ thời điểm nó từ bỏ quyền kiểm soát
- coroutines là người tiêu dùng dữ liệu trong khi trình tạo là nhà sản xuất dữ liệu
- có thể gửi các giá trị tới các coroutines dựa trên trình tạo [sử dụng câu lệnh send[] & [yield]] sau khi nó được khởi tạo trong khi các trình tạo thông thường không thể
AsyncIO — I/O không đồng bộ, vòng lặp sự kiện, coroutines và tác vụ
Từ tài liệu Python
Mô-đun này cung cấp cơ sở hạ tầng để viết mã đồng thời đơn luồng bằng cách sử dụng coroutines, ghép kênh truy cập I/O qua ổ cắm và các tài nguyên khác, chạy máy khách và máy chủ mạng. Chúng ta sẽ xem xét từng chủ đề dưới đây
Vòng lặp sự kiện là cốt lõi của mọi ứng dụng asyncio. Các vòng lặp sự kiện chạy các tác vụ và lệnh gọi lại không đồng bộ, thực hiện các hoạt động IO của mạng và chạy các quy trình con. Các nhà phát triển ứng dụng thường nên sử dụng các chức năng asyncio cấp cao, chẳng hạn như asyncio. run[], và hiếm khi cần tham chiếu đối tượng vòng lặp hoặc gọi các phương thức của nó
Quy trình tạo AsyncIO
Trong trăn 3. 4, coroutines dựa trên trình tạo được tạo bằng trình trang trí
def magic_pot[start=1, end=1000]:7 bằng thư viện mô-đun asyncio mới. Các coroutine của trình tạo Asyncio sử dụng cú pháp
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
def magic_pot[start=1, end=1000]:5 để tạm dừng coroutine
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
Một asyncio coroutine có thể
- "đầu ra từ" một coroutine khác
- “sản lượng từ” một tương lai
- trả về một biểu thức
- tăng ngoại lệ
Câu lệnh
def magic_pot[start=1, end=1000]:5 từ bỏ quyền điều khiển trở lại vòng lặp sự kiện để cho các coroutine khác thực thi
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
- Cú pháp “yield from” được giới thiệu trong PEP 380, thay vì cú pháp yield ban đầu cho coroutine của trình tạo. "yield from" được sử dụng bên trong các coroutines của máy phát điện.
def magic_pot[start=1, end=1000]:
5iterator hoặc coroutines bản địa/trình tạo/tương lai
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
... - Cho phép trình tạo sử dụng “yield from” để gọi các coroutine gốc [def async] và cũng cho phép coroutine của trình tạo được gọi bởi các coroutine gốc bằng cách sử dụng biểu thức đang chờ
- Việc sử dụng "yield" khiến chúng trở thành trình tạo/trình lặp thông thường phải được lặp lại và không hoạt động với các phương thức asyncio
import randomdef simple_generator[]:8
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Coroutines bản địa
def read_file[file_name]:1 từ khóa được giới thiệu kể từ Python 3. 5 giúp ngữ pháp lập trình coroutine thêm ý nghĩa và cú pháp mới nhất
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']
- async def trả về một đối tượng coroutine gốc. async def chức năng luôn là coroutine, ngay cả khi không có sự chờ đợi
- Trình tạo thông thường trả về một đối tượng trình tạo
- không đồng bộ. coroutine trả về đối tượng coroutine dựa trên trình tạo
- các loại. coroutine trả về đối tượng coroutine dựa trên trình tạo
def magic_pot[start=1, end=1000]:0
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
chờ đợi
- “await” nên được sử dụng với async def.
def read_file[file_name]:
2 được sử dụng để lấy kết quả thực thi của một đối tượng coroutine
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5'] - async/await tương đương mới nhất với @asyncio. coroutine/'sản lượng từ'
- await hoạt động trên các đối tượng trình tạo/coroutines gốc và trên đối tượng có phương thức __await__ trả về một trình vòng lặp
- Dưới vỏ bọc,
def read_file[file_name]:
2 mượn triển khai từ
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']def magic_pot[start=1, end=1000]:
5 với một kiểm tra bổ sung nếu đối số của nó thực sự là một chờ đợi
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
... - quy trình gốc/trình tạo, tương lai, các nhiệm vụ được chờ đợi
def magic_pot[start=1, end=1000]:4
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
Các Coroutine đồng thời [async/await, @asyncio. coroutine/năng suất từ]
def magic_pot[start=1, end=1000]:5
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
...
Câu lệnh coroutine compute[] “yield from” từ bỏ quyền điều khiển trở lại vòng lặp sự kiện [tạm dừng] và tiếp tục thực thi sau khi coroutine
def read_file[file_name]:5 hoàn thành. Lưu ý rằng bản thân
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']
def read_file[file_name]:5 là một quy trình đăng ký và quy trình đăng ký bị chặn sẽ tiếp tục sau khi ngủ. Vòng lặp sự kiện thực thi dựa trên các coroutine có thể chạy được và thứ tự thực hiện đầu ra [t1, t2, t3] thay đổi dựa trên độ trễ trong ví dụ
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']
Vòng lặp sự kiện
- Vòng lặp sự kiện sử dụng lập lịch hợp tác, nghĩa là vòng lặp sự kiện chạy một Tác vụ tại một thời điểm. Trong khi một Tác vụ đang chờ hoàn thành Tương lai, vòng lặp sự kiện sẽ chạy các tác vụ khác, gọi lại hoặc thực hiện các thao tác IO. Nhiệm vụ cũng có thể bị hủy bỏ
- Một vòng lặp Sự kiện được liên kết với một Chủ đề
- SelectorEventLoop — Vòng lặp sự kiện dựa trên mô-đun bộ chọn [epoll[]/kqueue[]/select[]] để ghép kênh I/O hiệu quả và cao cấp
- ProactorEventLoop — Vòng lặp sự kiện cho windows
import randomdef simple_generator[]:0
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
tương lai
def read_file[file_name]:7 là một đối tượng có thể chờ ở mức độ thấp đặc biệt đại diện cho kết quả cuối cùng của hoạt động không đồng bộ. Đối tượng tương lai được chờ đợi, điều đó có nghĩa là coroutine sẽ đợi cho đến khi Tương lai được giải quyết ở một số nơi khác
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']
import randomdef simple_generator[]:1
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Phối hợp giữa các hợp đồng tương lai
import randomdef simple_generator[]:2
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
nhiệm vụ
Nhiệm vụ là một lớp con của Tương lai. Các tác vụ được sử dụng để lên lịch cho các coroutine đồng thời trong vòng lặp sự kiện. Coroutine được bao bọc trong một Tác vụ với các chức năng như
def read_file[file_name]:8, coroutine sẽ tự động được lên lịch để chạy sớm. Tác vụ có add_done_callback[] để xử lý thêm việc dọn dẹp mã/xử lý logic
for row in open[file_name, "r"]:
yield row
def read_csv_row[file_name]:
for row in read_file[file_name]:
yield row.split[',']
def read_csv[file_name]:
for items in read_csv_row[file_name]:
print["Row: " + str[items]]
read_csv['test.csv']# Output:
Row: ['col1', 'col2', 'col3\n']
Row: ['1', '2', '3\n']
Row: ['3', '4', '5']
import randomdef simple_generator[]:3
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
@loại. công việc thường ngày
Trình trang trí để gắn cờ trình tạo là một coroutine. Rất giống với asyncio. coroutine[] và ít được chú ý hơn. Nó cho phép khả năng tương tác giữa các coroutine dựa trên trình tạo hiện có trong asyncio và các coroutine gốc [không đồng bộ]
import randomdef simple_generator[]:4
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Máy phát điện không đồng bộ
'yield' bên trong một coroutine gốc trả về một trình tạo không đồng bộ
import randomdef simple_generator[]:5
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Trình tạo có async/await được hỗ trợ với giao thức lặp không đồng bộ mới
Giao thức lặp không đồng bộ
- Phương thức __aiter__ trả về trình vòng lặp không đồng bộ
- Một phương thức __anext__ trả về một đối tượng có thể chờ đợi, sử dụng ngoại lệ StopIteration cho các giá trị “yield” và ngoại lệ StopAsyncIteration để báo hiệu kết thúc quá trình lặp
import randomdef simple_generator[]:6
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
không đồng bộ cho
Đơn giản hóa việc lặp lại trình tạo không đồng bộ [năng suất]
import randomdef simple_generator[]:73. Tóm lược
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
- Từ khóa 'yield' tạo trình tạo thông thường. 'yield from' là một phím tắt để lặp lại và làm cạn kiệt trình tạo
- máy phát điện. send[] giúp gửi các giá trị đến một coroutine. '[yield]' là hai hướng để lặp lại giữa các coroutine
- Vòng lặp sự kiện sử dụng lập lịch hợp tác. Các tác vụ đồng thời được lên lịch trong Vòng lặp sự kiện được quản lý bởi Chủ đề
- @asyncio. coroutine tạo các đối tượng coroutine trình tạo asyncio và sử dụng 'yield from' để hoạt động trên các coroutine gốc/trình tạo. Câu lệnh
def magic_pot[start=1, end=1000]:
5 từ bỏ quyền điều khiển trở lại vòng lặp sự kiện để cho các coroutine khác thực thi
while True:
yield random.randint[start, end]gen = magic_pot[]
for a in gen:
print[a]# Output: prints numbers without stopping
569
... - @loại. coroutine tương tự như @asyncio. coroutine giúp chuyển đổi các trình tạo thông thường thành các đối tượng coroutine và có thể tương tác giữa các coroutine bản địa
- asyncio là một thư viện để viết mã đồng thời bằng cú pháp async/await
- các coroutines được khai báo với cú pháp async/await là cách ưa thích để viết các ứng dụng asyncio
- async/await tương đương mới nhất với @asyncio. coroutine/'sản lượng từ'
- quy trình gốc/trình tạo, tương lai, các nhiệm vụ được chờ đợi
- Tương lai là một đối tượng có thể chờ ở mức độ thấp đặc biệt đại diện cho kết quả cuối cùng của hoạt động không đồng bộ
- Nhiệm vụ là một lớp con của Tương lai. Các tác vụ được sử dụng để lên lịch cho các coroutine đồng thời trong vòng lặp sự kiện để thực thi
- 'async for' được sử dụng để lặp qua trình tạo không đồng bộ
- 'async with' được sử dụng để thực hiện các thao tác không đồng bộ với dọn dẹp [thu gom rác]
import randomdef simple_generator[]:8
yield 10
yield 100
gen = simple_generator[]
print[gen]
print[next[gen]]
print[gen.__next__[]]
try:
print[next[gen]]
except StopIteration:
print['iteration stopped']# Output:
10
100
iteration stopped
Người giới thiệu
Đặc biệt Cảm ơn tất cả những người đã giúp tôi hiểu các khái niệm phức tạp với blog/bài thuyết trình chi tiết của họ. Tôi đã sử dụng một phần định nghĩa/ví dụ tham khảo từ một số liên kết tham khảo
- www. dabeaz. com trình bày xuất sắc và mã nguồn
- Abu Ashraf Masnun đã viết những bài báo xuất sắc về những chủ đề này. Kiểm tra blog của anh ấy [http. // masnun. com]
- https. //trăn thật. com/async-io-python/#other-features-async-for-and-async-generators-comprehensions
- https. //www. giáo dục. io/blog/python-concurrency-make-sense-of-asyncio
- https. // cáu kỉnh. ca/how-the-heck-does-async-await-work-in-python-3-5/
Vui lòng cho tôi biết phản hồi/chỉnh sửa của bạn về định nghĩa/mã. Nếu bạn đang đọc dòng cuối cùng này, bạn đã có rất nhiều kiên nhẫn/quan tâm để đọc một bài viết dài như vậy và cảm ơn vì điều đó. ]