0

I'm trying to multithread my Python application. This is how i thought the application would work:

  1. A list of ipv4 addresses is created by the user
  2. For each ipv4 address, the application establishes an SSH connection and logs in. This part would benefit from multithreading since each device takes about 10 seconds to complete. The ssh bit is all handled by my ConfDumper class.
  3. in each thread, a bit of data is fetched from the network device and should be returned to the main thread (where there is a list of devices)
  4. Once all threads are done, a result is presented.

Being new to Python and having no experience with multithreading, I've tried something like this:

import threading
import confDumper

class MyThread (threading.Thread):
    device = None

    # A device object is sent as agument
    def __init__(self, device):
        threading.Thread.__init__(self)
        self.device = device

    def run(self):
        print "Starting scan..."
        self.sshscan()
        print "Exiting thread"


    def sshscan(self):
        s = confDumper.ConfDumper(self.device.mgmt_ip, self.device.username, self.device.password, self.device.enable_password)
        t = s.getConf()

        if t:
            # We got the conf, return it to the main thread, somehow...

It seems to be working when I debug the code and step though the lines one by one, but once the thread is closed all results from the thread are lost. How do I return the result to the main thread?

user3305609
  • 145
  • 1
  • 9
  • 1
    Please don't declare class-level attributes like your `device` when you in fact mean them to be instance-attributes. It's not how Python does it, and it will bite you in the future if you happen to make it a mutable thing instead of None. – deets May 17 '15 at 13:02
  • See http://stackoverflow.com/questions/6893968/how-to-get-the-return-value-from-a-thread-in-python – Paul Rooney May 17 '15 at 13:26
  • @deets Please explain that a bit more. I've got a feeling that was wrong but how should you do it? – user3305609 May 17 '15 at 13:29
  • 1
    You simply remove the line with the `device = None` at class-level. Instance-attributes __should__ be declared at `__init__`, you actually can create them at any method/time - but it's considered bad style & will be flagged by any self-respecting linter. – deets May 17 '15 at 13:33

2 Answers2

1

You can use a Queue:

 import Queue
 import threading
 import random
 import time


 class Worker(threading.Thread):

     def __init__(self, queue):
         super(Worker, self).__init__()
         self._queue = queue


     def run(self):
         time.sleep(5.0 * random.random())
         self._queue.put(str(self))


 queue = Queue.Queue()
 workers = [Worker(queue) for _ in xrange(10)]

 for worker in workers:
     worker.start()

 for worker in workers:
     worker.join()

 while queue.qsize():
     print queue.get()
deets
  • 6,285
  • 29
  • 28
0

This was much easier than I thought. As far as I can see you don't have to return anything, the object sent to the thread is the same as the source.

user3305609
  • 145
  • 1
  • 9