Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.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,目标:运行main(),包括start\u time和end\u time import datetime as dt start_time, end_time= dt.time(9, 29), dt.time(16, 20) current\u time()只是不断地将当前时间添加到工作空间中。此时间用于此处未显示的脚本中的几个不同点 async def current_time(): while True: globals()['now'] = dt.datet

目标:运行
main()
,包括
start\u time
end\u time

import datetime as dt

start_time, end_time= dt.time(9, 29), dt.time(16, 20)
current\u time()
只是不断地将当前时间添加到工作空间中。此时间用于此处未显示的脚本中的几个不同点

async def current_time(): 
    while True:
        globals()['now'] = dt.datetime.now().replace(microsecond=0)
        await asyncio.sleep(.001)
另一个做某事的函数:

async def balance_check():
    while True:    
        #do something here
        await asyncio.sleep(.001)
main()
等待前面的协同程序:

async def main():
    while True:
#Issue:This is my issue. I am trying to make these
#coroutines only run between start_time and end_time. 
#Outside this interval, I want the loop to 
#shut down and for the script to stop.
        if start_time < now.time() < end_time : 

            await asyncio.wait([
                    current_time(),
                    balance_check(),
                    ])
        else:
            print('loop stopped since {} is outside {} and {}'.format(now, start_time, end_time))
            loop.stop() 


loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(main())
finally:
    loop.close()
async def main():
尽管如此:
#问题:这是我的问题。我正试着做这些
#协同路由仅在开始时间和结束时间之间运行。
#在此间隔之外,我希望循环
#关闭并使脚本停止。
如果开始时间

问题:即使在结束时间后仍能继续工作

问题在于不正确使用了
wait asyncio.wait([current_time(),balance_check(),])

waiting
asyncio.wait()
等待指定的等待项完成,即返回值或引发异常。由于
current\u time
balance\u check
都不会从无限循环中返回,因此
main()
的执行永远不会通过
wait asyncio.wait(…)
,因为此表达式等待这两个循环完成。反过来,
main()
中的
while
循环永远不会进入第二次迭代,
loop.stop()
没有机会运行

如果代码的目的是使用
asyncio.wait()
来给协同程序一个运行的机会,那么
asyncio.wait
就不是这个工具。相反,可以通过调用
asyncio.create_task()
来启动这两个任务,然后什么也不做。只要事件循环可以运行(即,它没有被调用
time.sleep()
或类似功能阻止),asyncio将自动在协同程序之间切换,在这种情况下,
current\u time
balanced\u check
以~1毫秒的速度切换。当然,您希望在
结束时间
截止日期之前重新获得控制权,因此“什么也不做”最好表示为对
asyncio.sleep()的单个调用:

请注意,甚至不需要显式的
loop.stop()
,因为
run\u until\u complete()
将在给定的协同程序完成后自动停止循环。对任务调用
cancel()
没有实际效果,因为循环几乎立即停止;它是用来完成这些任务的,这样垃圾回收器就不会在销毁挂起的任务时发出警告

如注释中所述,此代码不会等待
开始时间
,但在生成任务之前,通过添加另一个睡眠可以轻松完成此功能。

您可以使用此功能,特别是
事件

将日期时间导入为dt
导入异步
异步定义函数(开始事件、结束事件):
#等待,直到我们获得启动事件命令。
等待启动事件。等待()
#运行函数,直到将end_事件设置为true。
索引=0
而不是结束\u事件。是否设置了\u()
打印(f“函数正在运行;索引{index}.”)
等待异步睡眠(2)
指数+=1
异步def控制器(开始事件、结束事件):
#通常是这样。出于测试目的注释掉。可以通过主干道。

#减法/加法在dt.datetime()上不起作用。不平等是(>或者你的问题是什么?你展示的代码有什么问题?@mkrieger1 edited如果我错了,请纠正我,但我正在试图理解你为什么要这样做。我所能想到的是你(1)想先运行一个函数,或者从其他地方调用另一个函数,(2)您希望在特定时间运行函数,或(3)你这样做是为了练习?我不确定。你能指定吗?你必须使用asyncio吗?@FelipeFaria在这个脚本中,我同时使用asyncio和循环运行一系列函数/协同程序。但是我希望整个脚本只在开始时间和结束时间之间运行。谢谢你的澄清答案。能够使用
asyncio.create_task
我不得不升级到Python>3.7。现在,当我使用你的
main()
而不是我的时,我得到
RuntimeError:当另一个循环正在运行时无法运行事件循环。
当我去掉整个循环对象(上面代码的最后6行)而改用
asyncio.run(main())
,我得到
运行时错误:无法从正在运行的事件循环调用asyncio.run()
有什么想法吗?@FelipeFaria您的评论不正确-与协同程序对象不同,任务不必等待执行,它们由事件循环“在后台”自动执行。如果你不相信,你可以简单地从答案中运行代码,并注意到它是有效的。没问题,现在我只希望我能摆脱否决票。:)关于等待
开始
,这很简单,只需在生成任务之前添加睡眠即可。@FelipeFaria进行了编辑(关于等待开始时间的信息),谢谢你的坦率!@user4815162342当然——我们在这里应该是诚实的
async def main():
    t1 = asyncio.create_task(current_time())
    t2 = asyncio.create_task(balance_check())
    end = dt.datetime.combine(dt.date.today(), end_time)
    now = dt.datetime.now()
    await asyncio.sleep((end - now).total_seconds())
    print('loop stopped since {} is outside {} and {}'.format(now, start_time, end_time))
    t1.cancel()
    t2.cancel()