简体   繁体   English

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

[英]asyncio polling in the background with infinite printing

I would like to get a basic idea working in Python: 我想得到一个在Python中工作的基本想法:

Let's say I have a blocking call to a function that reads the current speed of a car (I use python-can for this, and wait for the corresponding message to appear on the bus). 假设我对读取汽车当前速度的函数进行了阻塞调用(为此我使用python-can,然后等待相应的消息出现在公交车上)。

On the other hand, I have an infinite loop that prints as precisely as possible the speed of the car. 另一方面,我有一个无限循环,可以尽可能精确地打印汽车的速度。

What I would like is the value of the speed to be updated directly, so that the infinite loop can print it as soon as it changes. 我想要的是直接更新速度的值,以便无限循环可以在更改时立即打印它。

Right now I had three ideas: 现在我有三个想法:

  • Call my get_speed function in the loop, and block. 在循环中调用我的get_speed函数,然后进行阻止。 This works, but only if this is the only value I am willing to print (spoiler alert: it's not). 这有效,但是仅当这是我愿意打印的唯一值时(扰流板警报:不是)。 If I want to print precisely the RPM too, I have to wait for the speed to be found, possibly missing multiple RPM value before. 如果我也想精确打印RPM,则必须等待速度找到,然后可能会丢失多个RPM值。
  • Create another "thread" (subprocess/multiprocessing/thread, whatever you call it) that updates a global variable. 创建另一个更新全局变量的“线程”(子进程/多处理/线程,无论您如何称呼)。 I know this works, but meh, I feel like I could have something smarter 我知道这可行,但是,我觉得我可以拥有一些更聪明的东西
  • From what I saw in javascript, there is a way to ask a function for a result, and keep going until this result is found (this rings some CPU bells right now ahah). 根据我在javascript中看到的,有一种方法可以向函数询问结果,并一直进行下去直到找到该结果(这会立即敲响一些CPU铃声)。 I kinda want something like this, which could make me do the following 我有点想要这样的东西,这可能会使我执行以下操作
speed = get_speed()
rpm = get_rpm()

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

This would (in my fairy world) actually display something like this: 实际上(在我的仙境中)这将显示以下内容:

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.

Right now what I have is something like this, which doesn't work (at all) 现在我所拥有的是这样的东西,(完全不起作用)

#!/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))

My two questions are: 我的两个问题是:

  1. Is this the most correct way to do it (--> asyncio, I mean), and if not what is ? 这是最正确的方法(我是说-> asyncio),如果不是,那是什么?
  2. If it is, can somebody help me understanding asyncio better :) 如果是这样,有人可以帮助我更好地理解异步:)

Thanks in advance all! 预先谢谢大家!

I was able to get the expected result like this: 我能够得到这样的预期结果:

#!/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()))

Is there a smarter way ? 有没有更聪明的方法?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM