python - 无限打印在后台进行异步轮询

标签 python multithreading python-asyncio

我想得到一个在Python中工作的基本想法:

假设我对读取汽车当前速度的函数进行了阻塞调用(为此我使用python-can,然后等待相应的消息出现在公交车上)。

另一方面,我有一个无限循环,可以尽可能精确地打印汽车的速度。

我想要的是直接更新速度的值,以便无限循环可以在更改时立即打印它。

现在我有三个想法:

  • 在循环中调用我的get_speed函数,然后进行阻止。这有效,但是仅当这是我愿意打印的唯一值时(扰流板警报:不是)。如果我也想精确打印RPM,则必须等待速度找到,然后可能会丢失多个RPM值。
  • 创建另一个更新全局变量的“线程”(子进程/多处理/线程,无论您如何称呼)。我知道这可行,但是,我觉得我可以拥有一些更聪明的
  • 从我在javascript中看到的情况,有一种方法可以向函数询问结果,并一直进行下去直到找到该结果(这会立即敲响一些CPU的钟声,呵呵)。我有点想要这样的东西,这可能会使我执行以下

  • speed = get_speed()
    rpm = get_rpm()
    
    while True:
            print("RPM: {0} - Speed: {1}".format(rpm, speed))
    

    实际上(在我的童话世界中)这将显示以下内容:
    RPM: None - Speed: None  # Function haven't returned yet, waiting
    RPM: None - Speed: None  # Same here
    RPM: None - Speed: None  # Same here
    RPM: 300 - Speed: None   # get_rpm has returned
    RPM: 300 - Speed: None   # Nothing happened
    RPM: 303 - Speed: 0      # get_rpm and get_speed have returned
    RPM: 303 - Speed: 0
    RPM: 312 - Speed: 0      # etc.
    

    现在我所拥有的是这样的东西,(完全不起作用)
    #!/usr/bin/env python3
    
    import datetime
    import asyncio
    import random
    from time import sleep
    
    async def _can_get_speed():
        # My long function
        print ("In   can_get_speed")
        sleep(4)
        print ("Out  can_get_speed")
        r = random.randint(0, 10)
        print(r)
        return r
    
    async def can_get_speed():
        return await asyncio.gather(_can_get_speed())
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        speed = 0
        speed = loop.call_soon(can_get_speed, loop)
        loop.run_forever()
    
    
        while True:
            print("Speed: {0}".format(speed))
    

    我的两个问题是:
  • 这是做到这一点的最正确方法吗(-> asyncio,我的意思是),并且
    如果不是,那是什么?
  • 如果是,有人可以帮助我理解
    更好asyncio :)

  • 预先谢谢大家!

    最佳答案

    我能够得到这样的预期结果:

    #!/usr/bin/env python3
    
    import datetime
    import asyncio
    import random
    from time import sleep
    from multiprocessing import Process, Queue
    
    def can_get_speed(q):
        while True:
            print("IN get_speed")
            r = random.randint(1, 4)
            sleep(r)
            print("Return {0}".format(r))
            q.put(r)
    
    def can_get_rpm(q):
        while True:
            print("IN get_rpm")
            r = random.randint(1, 4)
            sleep(r)
            print("Return {0}".format(r))
            q.put(r)
    
    
    if __name__ == "__main__":
    
        q = Queue()
        q2 = Queue()
    
        p = Process(target=can_get_speed, args=(q,))
        p2 = Process(target=can_get_rpm, args=(q2,))
    
        p.start()
        p2.start()
    
        speed = None
        rpm = None
    
        while True:
            if not q.empty():
                speed = q.get()
            if not q2.empty():
                rpm = q2.get()
    
            print("Speed: {0} - RPM: {1} - {2}".format(speed, rpm, datetime.datetime.now()))
    

    有没有更聪明的方法?

    关于python - 无限打印在后台进行异步轮询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48140571/

    相关文章:

    python - 如何使用 Django REST Framework 进行身份验证

    python - url中的当前参数在django中的下一个url中设置

    c++ - 在 `std::future` 中运行循环直到破坏 - 惯用方式?

    java - 线程安全框架

    python - python aiohttp和asyncio没有循环事件

    python - 查找值最接近某个值的 k 个 dict 项

    python - 关于Python函数max()和ifelse结构耗时的问题

    python - 如何设计多线程GUI网络应用程序?

    python - Flask 与事件循环相结合

    Python websockets lib客户端持久连接(带类实现)