gpt4 book ai didi

python - 如何使用多线程 ping 一个 IP 地址范围

转载 作者:太空狗 更新时间:2023-10-30 03:00:25 25 4
gpt4 key购买 nike

假设我有以下 ip 范围“10.0.0.x”。我需要在这个 ips 范围内循环 - “10.0.0.1-255”,ping 每个 ips,并检查响应。

这是我的代码:

for ip in range(1, 256):
fullIP = '10.0.0' + ip
if(Ping(fullIP) == True):
print(fullIP + ' responded')
else:
print(fullIP + ' did not respond')

此代码有效,但不幸的是它非常慢。
我想通过多线程使其更有效率,所以我做了以下事情:

def PingRange(start, end):
for ip in range(start, end):
fullIP = '10.0.0' + ip
if(Ping(fullIP) == True):
print(fullIP + ' responded')
else:
print(fullIP + ' did not respond')

try:
thread.start_new_thread( PingRange, (1, 123))
thread.start_new_thread( PingRange, (123, 256))
except:
print "Error: unable to start thread"

这段代码也可以工作,但它可以工作得更好,更通用。
如果这段代码写得正确,那么我就不会不断地创建两个线程;我会创建操作系统允许的线程数。
有些计算机允许 8 个线程,有些只允许 4 个,有些甚至不允许线程。

如何让这个程序在 Python 中使用最大数量的线程?

最佳答案

这个问题很适合使用线程池。线程池以恒定数量的线程运行,获取工作项(函数或方法),并在其线程池中执行这些工作项。它具有内置队列,因此如果您将 100 个工作项目分配给一个包含 5 个线程的池,它将执行所有 100 个项目,但不会同时运行超过 5 个。

Python 中有两个内置线程池选项(取决于您使用的版本)- multiprocessing.dummy.Pool , 和 concurrent.futures.ThreadPoolExecutor . ThreadPoolExecutor 仅内置于 Python 3.x 中,但可从 PyPI 获得反向移植。 multiprocessing.dummy.Pool 在 2.6+ 中可用。使用 multiprocessing.dummy.Pool,您的代码变得如此简单:

import multiprocessing.dummy

def ping_range(start, end):
num_threads = # Number of threads to run in the pool.
p = multiprocessing.dummy.Pool(num_threads)
p.map(ping, [10.0.0.x for x in range(start,end)])

if __name__ == "__main__":
PingRange(0, 255)

下一个问题是num_threads 使用什么。我认为您对具有最大允许线程数的系统有轻微误解。您可以在任何系统上创建任意数量的 Thread 对象,实际上没有什么可以阻止您,但在某个时刻您将创建太多系统无法处理的线程它和性能将开始变得更差,而不是更好。

受 CPU 限制的应用程序(意味着它主要需要 CPU 来工作)的经验法则是运行与 CPU 一样多的线程。但是,此 ping 操作是 I/O-bound,这意味着大部分工作是将 ping 请求发送到外部系统,然后等待响应,不需要 CPU 执行任何操作。在这些情况下,通常可以使用超过 CPU 数量的数量。我们可以保守一点,使用 2 * number_of_cpus,但您可以尝试更大的数字。

import multiprocessing
num_threads = 2 * multiprocessing.cpu_count()

综合起来:

import multiprocessing.dummy
import multiprocessing

def ping(ip):
success = # Run the ping command here
if success:
print("{} responded".format(ip))
else:
print("{} did not respond".format(ip))
return success

def ping_range(start, end):
num_threads = 2 * multiprocessing.cpu_count()
p = multiprocessing.dummy.Pool(num_threads)
p.map(ping, [10.0.0.x for x in range(start,end)])

if __name__ == "__main__":
ping_range(0, 255)

关于python - 如何使用多线程 ping 一个 IP 地址范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29371091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com