Theo mặc định, asyncio chạy ở chế độ sản xuất. Để dễ dàng phát triển, asyncio có chế độ gỡ lỗi
Có một số cách để bật chế độ gỡ lỗi asyncio
Đặt biến môi trường thành
loop.call_soon_threadsafe[callback, *args]
4Sử dụng
Vượt qua
loop.call_soon_threadsafe[callback, *args]
5 đếngọi
Ngoài việc bật chế độ gỡ lỗi, hãy xem xét thêm
đặt mức nhật ký của thành
loop.call_soon_threadsafe[callback, *args]
8, ví dụ: đoạn mã sau có thể được chạy khi khởi động ứng dụnglogging.basicConfig[level=logging.DEBUG]
định cấu hình mô-đun để hiển thị cảnh báo. Một cách để làm điều đó là sử dụng tùy chọn dòng lệnh
loop.call_soon_threadsafe[fut.cancel]
2
Khi chế độ gỡ lỗi được bật
asyncio kiểm tra và ghi lại chúng;
Nhiều API asyncio không an toàn theo luồng [chẳng hạn như và các phương thức] đưa ra một ngoại lệ nếu chúng được gọi từ một luồng sai
Thời gian thực hiện của bộ chọn I/O được ghi lại nếu mất quá nhiều thời gian để thực hiện thao tác I/O
Các cuộc gọi lại mất hơn 100 mili giây được ghi lại. Thuộc tính
loop.call_soon_threadsafe[fut.cancel]
5 có thể được sử dụng để đặt thời lượng thực hiện tối thiểu tính bằng giây được coi là "chậm"
Đồng thời và đa luồng
Một vòng lặp sự kiện chạy trong một luồng [thường là luồng chính] và thực thi tất cả các lệnh gọi lại và Tác vụ trong luồng của nó. Khi một Tác vụ đang chạy trong vòng lặp sự kiện, không có Tác vụ nào khác có thể chạy trong cùng một luồng. Khi một Tác vụ thực thi một biểu thức
loop.call_soon_threadsafe[fut.cancel]6, Tác vụ đang chạy sẽ bị treo và vòng lặp sự kiện sẽ thực thi Tác vụ tiếp theo
Để lên lịch từ một chuỗi hệ điều hành khác, nên sử dụng phương thức. Ví dụ
loop.call_soon_threadsafe[callback, *args]
Hầu như tất cả các đối tượng asyncio không phải là luồng an toàn, đây thường không phải là vấn đề trừ khi có mã hoạt động với chúng từ bên ngoài Tác vụ hoặc gọi lại. Nếu cần mã như vậy để gọi API asyncio cấp thấp, phương pháp này nên được sử dụng, e. g
loop.call_soon_threadsafe[fut.cancel]
Để lên lịch cho một đối tượng coroutine từ một chuỗi hệ điều hành khác, nên sử dụng chức năng này. Nó trả về a để truy cập kết quả
async def coro_func[]: return await asyncio.sleep[1, 42] # Later in another OS thread: future = asyncio.run_coroutine_threadsafe[coro_func[], loop] # Wait for the result: result = future.result[]
Để xử lý các tín hiệu và thực thi các quy trình con, vòng lặp sự kiện phải được chạy trong luồng chính
Phương pháp này có thể được sử dụng với a để thực thi mã chặn trong một chuỗi hệ điều hành khác mà không chặn chuỗi hệ điều hành mà vòng lặp sự kiện chạy trong đó
Hiện tại không có cách nào để lên lịch cho coroutine hoặc gọi lại trực tiếp từ một quy trình khác [chẳng hạn như quy trình bắt đầu bằng ]. Phần liệt kê các API có thể đọc từ đường ống và xem bộ mô tả tệp mà không chặn vòng lặp sự kiện. Ngoài ra, các API của asyncio cung cấp một cách để bắt đầu một quy trình và giao tiếp với nó từ vòng lặp sự kiện. Cuối cùng, phương pháp nói trên cũng có thể được sử dụng với a để thực thi mã trong một quy trình khác
Chạy mã chặn
Không nên gọi trực tiếp mã chặn [liên kết với CPU]. Ví dụ: nếu một hàm thực hiện phép tính sử dụng nhiều CPU trong 1 giây, thì tất cả các tác vụ IO và Tác vụ không đồng bộ đồng thời sẽ bị trễ 1 giây
Một bộ thực thi có thể được sử dụng để chạy một tác vụ trong một luồng khác hoặc thậm chí trong một quy trình khác để tránh chặn luồng hệ điều hành bằng vòng lặp sự kiện. Xem phương pháp để biết thêm chi tiết
ghi nhật ký
asyncio sử dụng mô-đun và tất cả việc ghi nhật ký được thực hiện thông qua trình ghi nhật ký
async def coro_func[]: return await asyncio.sleep[1, 42] # Later in another OS thread: future = asyncio.run_coroutine_threadsafe[coro_func[], loop] # Wait for the result: result = future.result[]8
Mức nhật ký mặc định là
async def coro_func[]: return await asyncio.sleep[1, 42] # Later in another OS thread: future = asyncio.run_coroutine_threadsafe[coro_func[], loop] # Wait for the result: result = future.result[]9, có thể dễ dàng điều chỉnh
logging.getLogger["asyncio"].setLevel[logging.WARNING]
Ghi nhật ký mạng có thể chặn vòng lặp sự kiện. Bạn nên sử dụng một luồng riêng để xử lý nhật ký hoặc sử dụng IO không chặn. Ví dụ, xem
Phát hiện các coroutine không bao giờ chờ đợi
Khi một chức năng coroutine được gọi, nhưng không được chờ đợi [e. g.
logging.getLogger["asyncio"].setLevel[logging.WARNING]0 thay vì
logging.getLogger["asyncio"].setLevel[logging.WARNING]1] hoặc coroutine không được lên lịch với , asyncio sẽ phát ra một
import asyncio async def test[]: print["never scheduled"] async def main[]: test[] asyncio.run[main[]]
đầu ra
test.py:7: RuntimeWarning: coroutine 'test' was never awaited test[]
Đầu ra ở chế độ gỡ lỗi
test.py:7: RuntimeWarning: coroutine 'test' was never awaited Coroutine created at [most recent call last] File "../t.py", line 9, in asyncio.run[main[], debug=True] File "../t.py", line 7, in main test[] test[]
Cách khắc phục thông thường là đợi coroutine hoặc gọi hàm
async def main[]: await test[]
Phát hiện các ngoại lệ không bao giờ truy xuất
Nếu a được gọi nhưng đối tượng Tương lai không bao giờ được chờ đợi, thì ngoại lệ sẽ không bao giờ được truyền tới mã người dùng. Trong trường hợp này, asyncio sẽ phát ra thông báo nhật ký khi đối tượng Tương lai được thu gom rác