简体   繁体   English

Asyncio - 无休止的运行任务 - 修改pymodbus示例

[英]Asyncio - endless running tasks - modifying pymodbus example

I am working with asynchronous PyModbus server with the refreshing task, everything is asyncio-based and based on pymodbus example code, which can be found here: https://pymodbus.readthedocs.io/en/latest/source/examples.html#updating-server-example我正在使用具有刷新任务的异步 PyModbus 服务器,一切都是基于异步的并且基于 pymodbus 示例代码,可以在这里找到: https://pymodbus.readthedocs.io/en/latest/source/examples.html#更新服务器示例

I am not very experienced with asyncio (just a few tutorial and simple experiments which were working correctly but this is my first attempt in creating anything more complicated) and I think I'm missing something.我对 asyncio 不是很有经验(只有一些教程和简单的实验可以正常工作,但这是我第一次尝试创建更复杂的东西),我想我遗漏了一些东西。

In the example there is the asyncio.run(...) called in the __main__ part.在示例中,__ __main__部分调用了asyncio.run(...) However, I want to modify this code and therefore I would like to have the server started outside of __main__ , something like this:但是,我想修改这段代码,因此我想让服务器在__main__之外启动,如下所示:

async def myFunction(args):
    # do some other stuff
    asyncio.create_task(run_updating_server(run_args))

if __name__ == "__main__":
    cmd_args = get_commandline(
        server=True,
        description="Run asynchronous server.",
    )
    run_args = setup_updating_server(cmd_args)
    asyncio.run(myFunction(run_args), debug=True)

However, this doesn't create a nice, endless running task as in the example, everything is performed just once and that's all, the program finishes.然而,这并没有像示例中那样创建一个漂亮的、无休止的运行任务,所有的事情都只执行一次,仅此而已,程序结束了。
I don't understand what is the difference and why was the server running endlessly in the example but runs only once in my modification - is there something in create_task() vs run() functionalities that I'm missing?我不明白有什么区别,为什么服务器在示例中无休止地运行,但在我的修改中只运行一次——我在create_task()run()功能中是否缺少某些东西?

I have found this topic and tried implementing it with explicit call of the event loop like this:我找到了这个主题并尝试通过像这样显式调用事件循环来实现它:

async def new_main(args):
    asyncio.Task(run_updating_server(args))

if __name__ == "__main__":
    cmd_args = get_commandline(
        server=True,
        description="Run asynchronous server.",
    )
    run_args = setup_updating_server(cmd_args)
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        loop.run_until_complete(new_main(run_args))
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()

However, in such case I just got Task was destroyed but it is pending!但是,在这种情况下,我刚刚得到Task was destroyed but it is pending! errors...错误...

My second question is: how should I properly implement task to have it endlessly running - the server, the updating function and some other which I want to implement (not related to the modbus server, just running along it and doing their things)?我的第二个问题是:我应该如何正确地执行任务以让它无休止地运行——服务器、更新 function 和其他一些我想实现的(与 modbus 服务器无关,只是沿着它运行并做他们的事情)? I want to add some tasks to the event loop and have them run endlessly, let's say - one should be executed every 1 second, another one should be triggered by some lock, etc. I thought that the updating task() in the example was changing the values on the server once every second but after investigating I see that it doesn't - it is just executed once.我想向事件循环中添加一些任务并让它们无休止地运行,比方说 - 一个应该每 1 秒执行一次,另一个应该由某个锁触发,等等。我认为示例中的updating task()是每秒更改一次服务器上的值,但在调查后我发现它没有 - 它只执行一次。 How can it be modified to behave as mentioned - increment the server values every second?如何将其修改为如上所述的行为 - 每秒递增服务器值?

I guess that's something obvious but lack of experience with asyncio and two days of brainstorming over the whole application made me too dumb to understand what am I missing... I hope you will be albo to guide me to right direction - TIA!我想这是显而易见的事情,但缺乏使用 asyncio 的经验以及对整个应用程序进行两天的头脑风暴让我太笨了,无法理解我错过了什么......我希望你能引导我走向正确的方向 - TIA!

What you are missing is the await keyword.您缺少的是await关键字。 An asyncio task without an await expression is almost always an error.没有 await 表达式的 asyncio 任务几乎总是一个错误。

async def myFunction(args):
    # do some other stuff
    t = asyncio.create_task(run_updating_server(run_args))
    await t

There is a huge difference between this function and the one in your code.这个 function 和你的代码中的有很大的不同。 Both functions create a task.这两个函数都创建一个任务。 Your code is then finished.你的代码就完成了。 It immediately exits and your program ends.它立即退出并且您的程序结束。 The function given here await s completion of the newly created task.这里给出的function await新创建的任务完成。 It doesn't progress past the await expression until the task run_updating_server is complete.在任务run_updating_server完成之前,它不会通过 await 表达式。 The program will not exit until myFunction ends, so the program keeps running until the task finishes.myFunction结束之前程序不会退出,因此程序会一直运行直到任务完成。 If the task is an infinite loop, the program will run forever.如果任务是一个无限循环,程序将永远运行下去。

You say you want to do other things in addition to running this server.你说除了运行这个服务器你还想做其他事情。 Probably each of those other things should be another task, created before the server.可能其他每件事都应该是另一个任务,在服务器之前创建。 You don't have to await on these tasks unless you want one (or more) of them to finish before the server starts.您不必等待这些任务,除非您希望其中一项(或多项)在服务器启动之前完成。 I'm not sure of what else you want to do, but the point of my answer is that your main task has to await something to keep the program from exiting immediately.我不确定你还想做什么,但我的回答是你的主要任务必须await一些东西来阻止程序立即退出。

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

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