ThreadPoolExecturor 未来永远不会完成
ThreadPoolExecturor future never finishing
我正在为一个程序编写后端,该程序需要能够 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)
这段代码在我的电脑上 运行 和 python3 工作正常,并为我提供了网络上的设备列表。
但是当我将此代码实施到我的烧瓶应用程序中时,未来永远不会完成,导致它挂在它尝试扫描的第一个 ip 上。以下代码来自我的烧瓶应用程序。
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
我正在寻找关于为什么未来没有解决的任何想法。
所以在挖掘 flask-socketIO 的源代码后,我发现 socketIO 喜欢占用线程。这意味着您必须使用 gevent 或 eventlet 自行修补它以使用另一个。 post 解释得很好,并引导我修复我的错误。
我正在为一个程序编写后端,该程序需要能够 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)
这段代码在我的电脑上 运行 和 python3 工作正常,并为我提供了网络上的设备列表。
但是当我将此代码实施到我的烧瓶应用程序中时,未来永远不会完成,导致它挂在它尝试扫描的第一个 ip 上。以下代码来自我的烧瓶应用程序。
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
我正在寻找关于为什么未来没有解决的任何想法。
所以在挖掘 flask-socketIO 的源代码后,我发现 socketIO 喜欢占用线程。这意味着您必须使用 gevent 或 eventlet 自行修补它以使用另一个。