2015-05-31 20 views
5

Tôi đang gặp sự cố khi tìm hiểu cách chuyển một tác vụ mới sang vòng lặp sự kiện đã chạy.hiểu asyncio đã chạy vòng lặp mãi mãi và các tác vụ đang chờ xử lý

Mã này:

import asyncio 
import logging 

@asyncio.coroutine 
def blocking(cmd): 
    while True: 
     logging.info("in blocking coroutine") 
     yield from asyncio.sleep(0.01) 
     print("ping") 

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    loop.run_forever() 
    asyncio.async(blocking("ls")) 

logging.basicConfig(level = logging.INFO) 
main() 

Thay đổi run_forever() để run_until_complete(asyncio.async(blocking("ls")) hoạt động tốt. Nhưng tôi thực sự bối rối - tại sao tôi không thể bỏ qua một nhiệm vụ trên vòng lặp đã chạy?

Trả lời

10

Vấn đề là cuộc gọi đến số loop.run_forever() khối; nó bắt đầu vòng lặp sự kiện và sẽ không trở lại cho đến khi bạn dừng vòng lặp một cách rõ ràng - do đó, forever một phần của run_forever. Chương trình của bạn không bao giờ dừng vòng lặp sự kiện một cách rõ ràng, do đó, bạn không bao giờ đạt được cuộc gọi asyncio.async(blocking("ls")).

Sử dụng asyncio.async để thêm tác vụ mới vào vòng lặp đang chạy là tốt, bạn chỉ cần đảm bảo chức năng thực sự được gọi từ bên trong một coroutine hoặc gọi lại bên trong vòng lặp sự kiện. Dưới đây là một số ví dụ:

Schedule blocking để chạy ngay sau khi vòng lặp bắt đầu sự kiện:

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    asyncio.async(blocking("ls")) 
    loop.run_forever() 

Schedule blocking từ một callback được thực hiện bởi các vòng lặp sự kiện:

def start_blocking(): 
    asyncio.async(blocking("ls")) 

def main(): 
    logging.info("in main funciton") 
    loop = asyncio.get_event_loop() 
    logging.info("new loop created") 
    logging.info("loop running forever") 
    loop.call_soon(start_blocking) # Calls start_blocking once the event loop starts 
    loop.run_forever() 
Các vấn đề liên quan