Python3 asyncio“任务已销毁,但正在挂起”,具有某些特定条件

威利尔

这是简化的代码,它使用python3协程并为SIGING和SIGTERM信号设置处理程序以正确停止作业:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import asyncio
import signal
import sys


def my_handler(signum, frame):
    print('Stopping')
    asyncio.get_event_loop().stop()
    # Do some staff
    sys.exit()


@asyncio.coroutine
def prob_ip(ip_addr):

    print('Ping ip:%s' % ip_addr)
    proc = yield from asyncio.create_subprocess_exec('ping', '-c', '3', ip_addr)
    ret_code = yield from proc.wait()
    if ret_code != 0:
        print("ip:%s doesn't responding" % ip_addr)
        # Do some staff
        yield from asyncio.sleep(2)
        # Do more staff
        yield from asyncio.sleep(16)


@asyncio.coroutine
def run_probing():

    print('Start probing')
    # Do some staff
    yield from asyncio.sleep(1)

    while True:
        yield from asyncio.wait([prob_ip('192.168.1.3'), prob_ip('192.168.1.2')])
        yield from asyncio.sleep(60)


def main():
    parser = argparse.ArgumentParser()
    parser.description = "Probing ip."
    parser.parse_args()

    signal.signal(signal.SIGINT, my_handler)
    signal.signal(signal.SIGTERM, my_handler)

    asyncio.get_event_loop().run_until_complete(run_probing())


if __name__ == '__main__':
    main()

当我通过以下方式运行它时:

python3 test1.py

按Ctrl-C可以停止,而不会发出任何警告。但是当我通过以下方式运行它时:

python3 -m test1

它通过Ctrl-C打印警告:

$ python3 -m test1 
Start probing
Ping ip:192.168.1.2
Ping ip:192.168.1.3
PING 192.168.1.2 (192.168.1.2): 56 data bytes
PING 192.168.1.3 (192.168.1.3): 56 data bytes
^C--- 192.168.1.2 ping statistics ---
--- 192.168.1.3 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
1 packets transmitted, 0 packets received, 100% packet loss
Stopping
Task was destroyed but it is pending!
task: <Task pending coro=<prob_ip() running at /tmp/test1.py:22> wait_for=<Future pending cb=[Task._wakeup()]> cb=[_wait.<locals>._on_completion() at /usr/lib/python3.4/asyncio/tasks.py:394]>
Task was destroyed but it is pending!
task: <Task pending coro=<prob_ip() running at /tmp/test1.py:22> wait_for=<Future pending cb=[Task._wakeup()]> cb=[_wait.<locals>._on_completion() at /usr/lib/python3.4/asyncio/tasks.py:394]>

如果通过以下方式安装此脚本,则会收到相同的警告:

from setuptools import setup

setup(name='some_scripts',
      version='1.0.0.0',
      author='Some Team',
      author_email='[email protected]',
      url='https://www.todo.ru',
      description='Some scripts',
      packages=['my_package'],
      entry_points={'console_scripts': [
          'test1=my_package.test1:main',
      ]},
      )

我的python版本是“ 3.4.2”

威利尔

好的。我想我已经弄清楚应该如何停止所有任务。

  1. 首先,据我了解。BaseEventLoop.stop()仅用于停止BaseEventLoop.run_forever()因此,应该通过Future.cancel取消所有任务要获取所有任务,可以使用Task.all_tasks静态方法。
  2. 取消后,将从run_until_complete引发所有任务asyncio.CancelledError异常。因此,如果不想将其打印到stderr,则应该抓住它。
  3. 而且,在某些情况下,我会收到此错误:TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object我发现了有关此错误的一些主题:

    他们都说可以在退出应用程序之前通过闭环来修复它。

这样我们得到以下代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import asyncio
import signal


def my_handler():
    print('Stopping')
    for task in asyncio.Task.all_tasks():
        task.cancel()


@asyncio.coroutine
def do_some(some_args):
    while True:
        print("Do staff with %s" % some_args)
        yield from asyncio.sleep(2)


def main():
    loop = asyncio.get_event_loop()

    loop.add_signal_handler(signal.SIGINT, my_handler)

    try:
        loop.run_until_complete(asyncio.wait([do_some(1), do_some(2)]))
    except asyncio.CancelledError:
        print('Tasks has been canceled')
    finally:
        loop.close()


if __name__ == '__main__':
    main()

它也可以与signal.signal一起使用但是正如文森特所注意到的, 在这种情况下,loop.add_signal_handler看起来更好。

但是我仍然不确定这是停止所有任务的最佳方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我在Python asyncio中收到“任务已销毁但正在挂起”错误?

来自分类Dev

使用异步错误“任务已销毁,但正在挂起”。(Python 3.4)

来自分类Dev

路由挂起中的Python3 Flask asyncio子进程

来自分类Dev

使用python3时Matplotlib挂起

来自分类Dev

Asyncio imap获取邮件python3

来自分类Dev

python3 asyncio 等待回调

来自分类Dev

如何在python3中的MongoDB中找到具有某些条件的最新文档?

来自分类Dev

Python3 Asyncio在并发任务之间共享资源

来自分类Dev

处理永不终止于python3 asyncio的任务

来自分类Dev

Python3 / Numpy:ndarray条件索引

来自分类Dev

或条件似乎在 Python3 中失败

来自分类Dev

在 lambda python3 中添加 if 条件

来自分类Dev

只有 Python3 的 Virtualenv

来自分类Dev

是否可以根据python3中的特定条件更新字典?

来自分类Dev

sudo python3运行的版本与没有sudo的运行python3的版本不同

来自分类Dev

python3中具有不同签名的多重继承

来自分类Dev

Python3具有循环功能/密码退出?

来自分类Dev

检查元素是否具有python3属性

来自分类Dev

Python3 - 具有读取文件功能的脚本

来自分类Dev

带有重复键的python3 csv + python defaultdict

来自分类Dev

如何使用asyncio在python3中运行并行作业?

来自分类Dev

在python3中调用递归函数fom if语句条件

来自分类Dev

在 Python3 中使用条件读取 excel 元组

来自分类Dev

根据条件 python3 将变量附加到列表

来自分类Dev

特定目录中的Python3列表文件

来自分类Dev

在python3中的特定路径中导入包

来自分类Dev

从python3的div中获取特定文本

来自分类Dev

在python3中为特定字符着色

来自分类Dev

将特定信息从 CSV 插入到 SQL python3

Related 相关文章

热门标签

归档