Python 使用无限打印在后台进行异步IO轮询

Python 使用无限打印在后台进行异步IO轮询,python,multithreading,python-asyncio,Python,Multithreading,Python Asyncio,我想了解一个使用Python的基本想法: 假设我对一个函数进行了阻塞调用,该函数读取汽车的当前速度(我使用python-can实现这一点,并等待相应的消息出现在总线上) 另一方面,我有一个无限循环,它尽可能精确地打印汽车的速度 我想要的是直接更新速度的值,这样无限循环可以在它改变时立即打印它 现在我有三个想法: 在循环中调用myget\u speed函数并阻塞。这是可行的,但前提是这是我唯一愿意打印的值(剧透警告:不是)。如果我也想精确地打印RPM,我必须等待找到速度,可能之前丢失了多个RPM

我想了解一个使用Python的基本想法:

假设我对一个函数进行了阻塞调用,该函数读取汽车的当前速度(我使用python-can实现这一点,并等待相应的消息出现在总线上)

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

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

现在我有三个想法:

  • 在循环中调用my
    get\u speed
    函数并阻塞。这是可行的,但前提是这是我唯一愿意打印的值(剧透警告:不是)。如果我也想精确地打印RPM,我必须等待找到速度,可能之前丢失了多个RPM值
  • 创建另一个更新全局变量的“线程”(subprocess/multiprocessing/thread,无论您如何称呼它)。我知道这很管用,但我觉得我可以有更聪明的东西
  • 从我在javascript中看到的情况来看,有一种方法可以向函数请求一个结果,并一直执行,直到找到这个结果为止(这就敲响了一些CPU的钟声啊哈)。我有点想要这样的东西,这可以让我做下面的事情
这将(在我的童话世界中)实际显示如下内容:

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
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()))
现在我有的是这样的东西,根本不起作用

我的两个问题是:

  • 这是最正确的方法吗(->asyncio,我的意思是),以及 如果不是,是什么
  • 如果是,有人能帮我理解吗 asyncio更好:)

  • 提前谢谢大家

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

    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
    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()))
    

    有没有更聪明的方法?

    当然,get_speed和get_rpm会在每次执行结束时以某种方式相互调用,或者找到一种方法在每次调用时为我获取最新的值(我认为python[generator with yield?]中有类似的方法)