我一直在尝试查找连接到具有特定掩码的网关的活动主机,但即使在线程化之后也需要花费很多时间。总主机也显示不正确。
CODE是:
import subprocess, sys, threading, time, queue
t = 0
[a,b,c,d] = list(sys.argv[1].split("."))
mask = int(sys.argv[2])
p = queue.Queue()
def alive(host):
reply = str(subprocess.Popen(["ping", "-n","1","-w","5",host],
stdout=subprocess.PIPE).communicate()[0])
if "TTL=" in reply :
if host != sys.argv[1]:
print(host," is UP")
p.put(1)
else:
p.put(0)
else:
p.put(0)
start_time = time.time()
if mask == 8:
for i in range(1,256):
for j in range(1,256):
for k in range(1,256):
iplist = [a,str(i),str(j),str(k)]
ip = '.'.join(iplist)
thread = threading.Thread(target = alive(ip))
thread.start()
elif mask == 16:
for i in range(1,256):
for j in range(1,256):
iplist = [a,b,str(i),str(j)]
ip = '.'.join(iplist)
thread = threading.Thread(target = alive(ip))
thread.start()
elif mask == 24:
for i in range(1,256):
iplist = [a,b,c,str(i)]
ip = '.'.join(iplist)
thread = threading.Thread(target = alive(ip))
thread.start()
else:
print("Mask must be 8 , 16 or 24")
for i in range(p.qsize()):
if p.get == 1:
t+=1
else:
pass
print("\nTotal no. of hosts connected to ",sys.argv[1], " is ",t)
print("Total time taken is ",time.time() - start_time)
命令行输入:
python uphost.py 192.168.1.1 24
输出:
192.168.1.20 is UP
192.168.1.30 is UP
Total no. of hosts connected to 192.168.1.1 is 0
Total time taken is 125.90091395378113
答案 0 :(得分:2)
您正在创建太多线程(256,256 ^ 2,256 ^ 3)。并且线程创建有一个开销,你需要平衡每个线程正在做的工作量。
我认为更好的解决方案是使用预定数量的线程池(请参阅https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool)(与您的机器支持的线程数一样多)。
答案 1 :(得分:0)
除了上面提到的使用太多线程的问题之外,你的实际问题(125秒)是你因为这个而没有使用线程进行ping命令
elif mask == 24:
for i in range(1, 256):
iplist = [a, b, c, str(i)]
ip = '.'.join(iplist)
thread = threading.Thread(target=alive(ip))
thread.start()
您正在主线程中调用alive(ip)
,并且该调用的返回是生成线程的目标..
你想做的是
elif mask == 24:
for i in range(1, 256):
iplist = [a, b, c, str(i)]
ip = '.'.join(iplist)
thread = threading.Thread(target=alive, args=[ip])
thread.start()
这是您的代码(非线程)的第一个问题。
修复后,您会发现另一个问题。您并没有等待线程完成,所以:
...
threads = []
...
elif mask == 24:
for i in range(1, 25):
iplist = [a, b, c, str(i)]
ip = '.'.join(iplist)
thread = threading.Thread(target=alive, args=[ip])
threads.append(thread)
thread.start()
...
for thread in threads:
thread.join()
for i in range(p.qsize()):
if p.get() == 1:
t += 1
else:
pass
此处添加的拼写错误修正为p.get
(不含()
)。
但你应该像{simpel01那样关注multiprocessing.Pool
,因为它更简单,更清晰,使用和管理线程池而不是进入spawn-frenzy模式:)
编辑>使用multiprocessing.Pool更新代码
import subprocess
import sys
import multiprocessing
import time
[a, b, c, d] = list(sys.argv[1].split("."))
mask = int(sys.argv[2])
def alive(host):
reply = str(
subprocess.Popen(
["ping", "-c", "1", "-t", "5", host], # edited for linux
stdout=subprocess.PIPE
).communicate()[0]
)
if "ttl=" in reply:
if host != sys.argv[1]:
print(host, " is UP")
return host
return None
def main():
ips = []
if mask == 8:
for i in range(1, 256):
for j in range(1, 256):
for k in range(1, 256):
iplist = [a, str(i), str(j), str(k)]
ips.append('.'.join(iplist))
elif mask == 16:
for i in range(1, 256):
for j in range(1, 256):
iplist = [a, b, str(i), str(j)]
ips.append('.'.join(iplist))
elif mask == 24:
for i in range(1, 256):
iplist = [a, b, c, str(i)]
ips.append('.'.join(iplist))
else:
print("Mask must be 8 , 16 or 24")
return
start_time = time.time()
pool = multiprocessing.Pool(processes=100)
hosts_up = [x for x in pool.map(alive, ips) if x]
print("\nTotal no. of hosts connected to ", sys.argv[1], " is ", len(hosts_up))
print("Total time taken is ", time.time() - start_time)
if __name__ == '__main__':
main()
结果
$ python3 uphosts.py 192.168.1.1 24
192.168.1.66 is UP
192.168.1.65 is UP
192.168.1.254 is UP
Total no. of hosts connected to 192.168.1.1 is 3
Total time taken is 15.280648946762085