zoukankan      html  css  js  c++  java
  • asyncio 中给running 的loop 动态添加 Future Task

    https://my.oschina.net/backbye/blog/1919486

    asyncio 提供了两个给运行中的事件循环(loop) 添加 事件的方法

    call_soon_threadsafe() 、run_coroutine_threadsafe()

    因为我们一般的场景中会另起一个线程来启动loop( loop.run_forever() ),所以上面两个方法设计成线程安全

    但是上面两个方法并不能满足我们全部的需要:

    1. run_coroutine_threadsafe 只能用于传入一个协程,而不能直接传入task对象(这样才方便我们在主进程中随时查看任务的执行情况和获取结果),当然可以去修改源码,但是不建议这么做

    2. run_forever 虽然解决了可以随时加入任务的问题,但是带来一个新的问题:这个线程会一直运行下去,除非ctrl-C, 因为1,所以我们无法根据任务的执行情况来loop.stop, 而且由于线程安全,即使你执行了loop.stop() 也不会起任何作用

    所以源头要回到线程安全上去解决,查看源码发现是通过一个管道文件来实现的,可以理解为内置了一个队列,一切对loop的修改都要通过发送一个信号到这个队列,才能同步到running loop的那个线程中,从而产生效果。

    发送信号代码:loop._csock.send(b'')

    下面给个示例,自己去体会

    import asyncio
    import threading
    
    def start_loop(loop):
        asyncio.set_event_loop(loop)
        loop.run_forever()
        print(asyncio.Task.all_tasks().pop().result())
        
        
    async def do_some_work(name):
        for i in range(5):
            print(f"{name}: is working")
            await asyncio.sleep(1)
        return True
            
    loop = asyncio.new_event_loop()
    
    threading.Thread(target=start_loop, args=(loop,)).start()
    
    task = loop.create_task(do_some_work("Lili"))
    
    loop._csock.send(b'')
    
    while True:
        if task.done():
            loop.stop()
            loop._csock.send(b'')
            break
    

      

  • 相关阅读:
    UVA120Stacks of Flapjacks
    [.NET] 基于windows mobile 5.0 开发环境配置说明
    C#实现UDP打洞
    webBrowser对跳转后的页面的处理
    Windows Mobile程序环境配置以及Windows Mobile与PC进行UDP通信总结
    C#【Fox即时通讯核心】 开发记录之三(知识储备:TCP UDP打洞)
    jqplot统计图工具简单例子
    订单编号
    windows mobile 5.0 PocketPC模拟器上网的设置 【正确】
    今明2年主要目标20112012
  • 原文地址:https://www.cnblogs.com/pythonClub/p/10014775.html
Copyright © 2011-2022 走看看