Python 如何使用多线程ping一系列IP地址

Python 如何使用多线程ping一系列IP地址,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,假设我有以下ip范围“10.0.0.x”。我需要在这个IP范围内循环——“10.0.0.1-255”,对每个IP进行ping,并检查响应 这是我的代码: for ip in range(1, 256): fullIP = '10.0.0' + ip if(Ping(fullIP) == True): print(fullIP + ' responded') else: print(fullIP + ' did not respond') 此代码可以工作,但不幸的是它

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

这是我的代码:

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中使用最大数量的线程?

此问题非常适合使用线程池。线程池使用固定数量的线程运行,获取工作项(函数或方法),并在其线程池中执行这些工作项。它有内置的队列,因此如果您将一百个工作项分配给五个线程的池,它将执行所有一百个工作项,但不会同时运行五个以上的工作项

Python中有两个内置线程池选项(取决于您使用的版本),和
ThreadPoolExecutor
仅在Python3.x中内置,尽管PyPI提供了一个后端口<代码>多处理.dummy.Pool在2.6+中提供。使用
多处理.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\u线程
。我认为您对系统允许的最大线程数有点误解。您可以在任何系统上创建任意数量的
Thread
对象,实际上没有任何东西会阻止您,但在某一点上,您将创建太多线程,系统将无法处理它,性能将开始变得更差,而不是更好

CPU受限的应用程序的经验法则(意味着它主要需要CPU来完成工作)是运行与CPU数量相同的线程。然而,这个ping操作是I/O绑定的,这意味着大部分工作是将ping请求发送到外部系统,然后等待响应,而不需要CPU做任何事情。在这些情况下,通常可以使用超过CPU数量的CPU。我们可以保守地使用
2*numberofcpu
,尽管您可以尝试使用更大的数字

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)

有些计算机允许8个线程,有些计算机只允许4个线程,有些甚至不允许线程。
那么我们在这里讨论的是什么样的体系结构?为什么体系结构与此相关?我希望代码在所有架构上都能尽可能高效地工作。因为现实中没有一个系统不能处理256个线程。我建议在这里添加更多细节,首先,你的“Ping”函数采用什么形式?因为这不是一个内置的(据我所知),第二,你有没有研究过多处理?特别是池功能?由于python使用全局解释器锁,一个进程中一次只能运行一个线程,这意味着通常使用多个线程实际上会降低任务的执行速度(而不是加快任务的执行速度)。要同时执行任务,您需要使用多个进程。多亏了这段代码非常简单且有效,但如果它有异常处理,那就更好了。有时,当我在其他计算机上运行此代码时,它会抛出异常。您能将异常处理添加到此代码中吗?