ThreadPoolExecturor的未来永远不会完结

时间:2020-09-03 14:18:56

标签: python python-3.x flask concurrent.futures

我正在为程序编写后端,该程序需要能够ping网络上的所有设备以查看它们是否存在。该后端在烧瓶插座上运行。我编写了一个简单的测试脚本,该脚本使用threadExecutor和Futures来完成此任务,以加快该过程。

import platform
import subprocess
import netifaces as ni
import concurrent.futures
import socket

baseIP = ni.ifaddresses('enp4s0')[ni.AF_INET][0]['addr']
prefix = '.'.join(baseIP.split('.')[0:3])
aliveIPs = []

def ping(ip):
    command = ['ping', '-c 1', '-w 5', ip]
    print(ip)
    if(subprocess.call(command) == 0):
        return socket.gethostbyaddr(ip)
    else:
        return ''

ips = [prefix + '.' +str(i) for i in range(0,255)]

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = []
    for ip in ips:
        futures.append(executor.submit(ping, ip=ip))
    for future in concurrent.futures.as_completed(futures):
        res = future.result()
        if(res != ''):
            aliveIPs.append(res)

print(aliveIPs)

此代码在我的PC上与python3一起运行时效果很好,并为我提供了网络上的设备列表。

但是,当我在我的flask应用程序中实现此代码时,将来永远都无法完成,导致它挂在它尝试扫描的第一个ip上。以下代码来自我的flask应用程序。

def ping(ip):
    print(ip)
    proc = subprocess.run(['ping', '-c 1', '-w 5', ip])
    if(proc == 0):
        print("alive")
        return socket.gethostbyaddr(ip)
    else:
        print("none")
        return ''


"""
gets a list of available hosts in the network for a connection
"""


def update_worker_list(executor):
    print("updating")
    network_device = get_network_info()['net_name']
    ip = ni.ifaddresses(network_device)[ni.AF_INET][0]['addr']
    ipPrefix = '.'.join(ip.split('.')[0:3])
    alive_ips = []

    ips = [ipPrefix + '.' + str(i) for i in range(0, 255)]
    futures = []
    for ip in ips:
        futures.append(executor.submit(ping, ip=ip))
    for future in concurrent.futures.as_completed(futures):
        res = future.result()
        if(res != ''):
            alive_ips.append(res)
    print(alive_ips)

此处的executor参数是flask-executor pip包中的flask_executor。它的设置如下:

app = Flask(__name__)
app.config['SECRET_KEY'] = DEV_SECRET
app.config['DEBUG'] = True
app.config['EXECUTOR_TYPE'] = 'thread'
app.config['EXECUTOR_MAX_WORKERS'] = 20
executor = Executor(app)

我最初使用python提供的执行程序尝试了此操作,但这导致了相同的错误。 以下是update_workers_list函数向STDOUT的输出:

updating
192.168.8.0
Do you want to ping broadcast? Then -b. If not, check your local firewall rules.
none

我对寻找未来无法解决的任何想法。

1 个答案:

答案 0 :(得分:0)

因此,在浏览了flask-socketIO的源代码之后,我发现socketIO喜欢占用线程。这意味着您必须自己使用gevent或eventlet猴子修补它以使用另一个。 this帖子对此进行了很好的解释,并引导我修复了我的错误。