加速Python脚本的for循环

use*_*990 2 python bash performance for-loop

假设你有这样的东西(从这里复制):

#!/usr/bin/python
from scapy.all import *

TIMEOUT = 2
conf.verb = 0
for ip in range(0, 256):
    packet = IP(dst="192.168.0." + str(ip), ttl=20)/ICMP()
    reply = sr1(packet, timeout=TIMEOUT)
    if not (reply is None):
         print reply.src, "is online"
    else:
         print "Timeout waiting for %s" % packet[IP].src
Run Code Online (Sandbox Code Playgroud)

在尝试下一个主机之前,无需等待每个ping完成.我可以每次将循环内部放入沿着&in 的行的背景中:

for ip in 192.168.0.{0..255}; do 
ping -c 1 $ip &
done
Run Code Online (Sandbox Code Playgroud)

Jor*_*dan 5

你应该做的第一件事是改变你的范围range(0, 256),使它包含0-255.

其次,您正在查看Python的线程,这在某种程度上类似于抽象级别的Bash进程守护进程.

导入多处理并创建池:

from multiprocessing.pool import ThreadPool
pool = ThreadPool(20)  # However many you wish to run in parallel
Run Code Online (Sandbox Code Playgroud)

所以进行ping查找,这是for循环中的所有内容,并使其成为一个函数.

def ping(ip):
    packet = IP(dst="192.168.0." + str(ip), ttl=20)/ICMP()
    reply = sr1(packet, timeout=TIMEOUT)
    if not (reply is None):
         print reply.src, "is online"
    else:
         print "Timeout waiting for %s" % packet[IP].src
Run Code Online (Sandbox Code Playgroud)

然后在你的for循环中,

for ip in range(0, 256):
    pool.apply_async(ping, (ip,))

pool.close()
pool.join()
Run Code Online (Sandbox Code Playgroud)

pool.join() 等待所有线程返回的是什么.