kyan001 / ping3

Pure Python3 version of ICMP ping, shipped with command-line command.
MIT License
317 stars 54 forks source link

Wrong Results when using Threading #26

Open IslamMouhsen opened 4 years ago

IslamMouhsen commented 4 years ago

when i used threads to ping multiple ips in the same time after the first request all other pings got None value and i found that all values got the same id image

kyan001 commented 4 years ago

Hi, can you run it in DEBUG mode? So I can figure out what is going on.

  1. import ping3; ping3.DEBUG = True
  2. run your codes.
  3. and then paste the outputs here.

and if you could show me your code that would be a great help.

JimJamUrCode commented 4 years ago

I am seeing a similar issue. I run this code on Ubuntu Linux 20.04 LTS and get IP addresses showing that I know are not on my network.

import threading
from queue import Queue

class ipInformation():
  def worker(self):
    while True:
      ip = self.q.get()
      self.pingIPTwo(ip)
      self.q.task_done()

  def scan(self):
    for x in range(1, 255):
      ip = "192.168.1." + str(x)
      self.q.put(ip)

    self.q.join()       # block until all tasks are done
    print("Done, workers/threads joined!!")

ipInfo = ipInformation()

for i in range(8):
  threading.Thread(target=ipInfo.worker, daemon=True).start()

ipInfo.scan()
fohrloop commented 3 years ago

Hi,

Thank you for the work for this package. I have also noticed very strange behavior when using threads. I am on Windows 10.

Here is an example, where I use the ping3 package with and without multithreading to ping three different addresses:

The parts where threads were used is marked with orange boxes. When using just single thread, there is no coloring.

What can be seen from the figure?

image

For reference, here is the simple piece of code used to make the pings behave reasonably with multithreading on Windows:

import re
import subprocess

def ping(addr, timeout=60):
    out = subprocess.check_output(
        ("ping", "-w", str(int(timeout) * 1000), addr)
    ).decode("utf-8")
    match = re.search(
        r"Minimum = (\d*).*?, Maximum = (\d*).*?, Average = (\d*).*?", out
    )
    if not match:
        return timeout
    return float(match.groups()[0]) / 1000