如何使这种多线程Python pinger更快?

时间:2018-12-06 17:43:02

标签: python python-3.x multithreading performance optimization

我的目标:我想对每个IPv4地址执行ping操作并记录它们是否响应。

我设置的方式是每个IP地址都对应一个索引。例如0.0.0.0是索引0,而0.0.1.0是索引256。因此,如果0.0.0.0响应,则位数组的第0个元素为true。

代码如下:

import subprocess
from bitarray import bitarray
import threading
import time

response_array = bitarray(256 * 256 * 256 * 256)
response_array.setall(False)

def send_all_pings():
    index = 0
    for f1 in range(256):
        for f2 in range(256):
            for f3 in range(256):
                for f4 in range(256):
                    thread = PingerThread(".".join(map(str, [f1, f2, f3, f4])), index)
                    thread.start()
                    index += 1

    time.sleep(30)
    print("Writing response array to file")
    with open('responses.bin', 'wb') as out:
        response_array.tofile(out)


class PingerThread(threading.Thread):
    def __init__(self, address, index):
        threading.Thread.__init__(self)
        self.address = address
        self.index = index

    def run(self):
        if subprocess.call(["ping", "-c", "1", "-w", "1", self.address]) == 0:
            response_array[self.index] = True
        else:
            response_array[self.index] = False

我该怎么做才能使其运行更快?即使有很小的优化,也欢迎任何优化!

谢谢

1 个答案:

答案 0 :(得分:0)

一些建议,大致按受益顺序排列:

  1. 尝试不启动“叉子炸弹”:您的代码尝试启动40亿个线程,每个线程都产生一个进程。这会使任何计算机瘫痪,您需要限制自己一次最多(最多)数百个进程

  2. 自己编写网络代码。启动整个线程并进行处理以发送和接收单个网络数据包的开销很大

  3. 您几乎可以肯定是IO受限而不是CPU,请使用asyncio库

假设您编写的代码每秒能够发送1万个数据包,这仍然需要5天左右的时间。如果您真的开始做某事,或者您的ISP严厉地限制/收费您所产生的数据,如果您的ISP很快阻止了您,这也不会令我感到惊讶。

如果您发送的ping过多,您将不会得到响应,这在设计上是“不可靠的”