Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 队列中的异步IO共享变量_Python_Python Asyncio - Fatal编程技术网

Python 队列中的异步IO共享变量

Python 队列中的异步IO共享变量,python,python-asyncio,Python,Python Asyncio,我正在学习Asyncio,到目前为止,我已经准备好了我需要的结构 import asyncio import random async def speed_forever(): while True: speed = random.randint(1,100) print("Speed mesuring ......", speed) await asyncio.sleep(1) async def rain_for

我正在学习Asyncio,到目前为止,我已经准备好了我需要的结构

import asyncio
import random

async def speed_forever():
    while True:
        speed = random.randint(1,100)
        print("Speed mesuring ......", speed)
        await asyncio.sleep(1)

async def rain_forever():
    while True:
        rain = random.random()
        print("Rain mesuring .......", rain)
        await asyncio.sleep(0.1)


async def main():
    asyncio.ensure_future(speed_forever())  # fire and forget
    asyncio.ensure_future(rain_forever())  # fire and forget

    while True:
        print("*" * 40)
        print("Sending Data.....")    #Here I'd like to get access to rain and speed variable by using a queue
        print("*" * 40)
        await asyncio.sleep(5)
     

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())


现在,我想从main()中获取雨和速度的信息,以便对这些变量进行处理(例如通过空中发送)

  • 我应该如何实现队列,因为我在这方面失败了
  • 代码结构是否足够好,可以开始用实际代码实现函数

  • 下面是一个框架,用于通过几个队列将数据从
    *\u永
    函数传回
    main
    。我已将新代码标记为“***”

    import asyncio
    import random
    
    rain_q = asyncio.Queue()      # ***
    speed_q = asyncio.Queue()     # ***
    
    async def speed_forever():
        while True:
            speed = random.randint(1,100)
            print("Speed mesuring ......", speed)
            await speed_q.put(speed)                 # ***
            await asyncio.sleep(1)
    
    async def rain_forever():
        while True:
            rain = random.random()
            print("Rain mesuring .......", rain)
            await rain_q.put(rain)                   # ***
            await asyncio.sleep(0.1)
    
    
    async def main():
        asyncio.ensure_future(speed_forever())  # fire and forget
        asyncio.ensure_future(rain_forever())  # fire and forget
    
        rain = None       # *** 
        speed = None      # ***
        while True:
            print("*" * 40)
    
            # *** Read stuff from the queues. Here, I'm just using the latest
            # item in the queue - but one can do other things as well. 
            while not rain_q.empty(): 
                rain = await rain_q.get()
            
            while not speed_q.empty(): 
                speed = await speed_q.get()
    
            print(f"*** Last rain was {rain}")            
            print(f"*** Last speed was {speed}")
            print("Sending Data.....")    #Here I'd like to get access to rain and speed variable by using a queue
            print("*" * 40)
            await asyncio.sleep(5)
    
         
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    

    请注意,如果您感兴趣的只是队列中的最后一项,那么还有其他方法可以实现这一点。例如,一个是具有最新编号的float类型的全局变量。在这种情况下,我认为这样做是不对的。

    speed\u forever
    rain\u forever
    应该是类的方法
    speed
    rain
    应该是同一类的属性。您想获取main中的所有测量值(例如,从最后5秒开始的测量值)还是仅获取最后一个测量值?最后一个可用的测量值。我现在看到speed已获取队列中设置的所有值。速度是88速度是44速度是89速度是23速度是82有没有办法从队列中获取最新的速度值然后清除它?如果我理解正确,你基本上是在寻找大小为1的队列,它总是只保留最后一项?是的,我每3秒获取一个新值,但可能每分钟在空中发送最后一个值(平均值)
    ,而
    main()中的
    循环不正确。当队列变为空时,内部循环将不会进入,外部循环将永远循环。由于外部循环不等待任何东西,因此不会运行其他协程并有机会将某些东西放入队列中。正确(且更简单)的方法是删除内部循环,只需在外部
    中无条件地使用
    rain=wait rain\u q.get()
    ,而在外部
    中使用True
    。如果队列不为空,则将给出下一项。如果它是空的,
    get()
    将暂停当前协同程序,直到有项目可用为止-这正是您想要的。@Dan您说得对。不过,该评论的其余部分仍应适用。