簡體   English   中英

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

[英]How to ping a range of IP addresses using multithreading

假設我有以下ip范圍“10.0.0.x”。 我需要循環這個范圍的ips - “10.0.0.1-255”,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中有兩個內置的線程池選項(取決於您使用的版本) - multiprocessing.dummy.Poolconcurrent.futures.ThreadPoolExecutor ThreadPoolExecutor僅內置在Python 3.x中,盡管PyPI提供了一個backport。 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限制,這意味着大多數工作是將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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM