2

I'm using vanilla Python 2.7 loaded with Cygwin

I want to be able to spawn a thread subclass that calls a top-level function, and the top-level function spawns separate threads calling sub-level functions. Here's pseudo-code

import threading

#!/usr/bin/python
import threading

class Server(threading.Thread):
    def __init__(self, threadID, target):
        self.__threadID = threadID
        self.__target = target
        threading.Thread.__init__(self)

    # Function called when the thread's start() function is called
    def run(self):
        self.target()
        pass

    # This is the top level function called by other objects
    def reboot(self):
        # I want this function to spawn two threads
        # - First thread calls the __powerDown() function
        # - Secod thread calls the __powerUp() function, and pends
        #   until __powerDown() thread finishes
        pass

    def __powerDown(self):
        # What to put here?
        pass

    def __powerUp(self):
        # What to put here?
        pass

    __threadID = ''
    __target = None


# Code calling above code
server = Server(123, reboot) # Will this work?
Chris F
  • 14,337
  • 30
  • 94
  • 192
  • Actually there was a mistake in my code (missing `target` keyword). Please have a look at the code now, since your edit was not correct (it was calling a function instead of passing it to a thread). – freakish Sep 24 '13 at 19:51

2 Answers2

2

Something like this?

import threading

class Server(threading.Thread):
    # some code

    # This is the top level function called by other objects
    def reboot(self):
        # perhaps add a lock
        if not hasattr(self, "_down"):
            self._down = threading.Thread(target=self.__powerDown)
            self._down.start()
            up = threading.Thread(target=self.__powerUp)
            up.start()

    def __powerUp(self):
        if not hasattr(self, "_down"):
            return
        self._down.join()
        # do something
        del self._down
freakish
  • 54,167
  • 9
  • 132
  • 169
  • How can I extend your solution to three threads? That is, 1) start __powerDown thread, when done, 2) start __doSomething thread, when done, 3) start __powerUp thread – Chris F Sep 30 '13 at 20:13
0

There's lots of ways to do this, I'm most familiar with ThreadPools, and they have a very easy interface for calling threads and joining them...

from multiprocessing.pool import ThreadPool

# This is the top level function called by other objects
def reboot(self):
    # setup your thread pool:
    reboot_pool = ThreadPool()
    # - First thread calls the __powerDown() function
    power_down = reboot_pool.apply_async(self.__powerDown())
    # this will block until it finishes
    power_down.get()
    # - Secod thread calls the __powerUp() function
    power_up = reboot_pool.apply_async(self.__powerUp())
    #   block until __powerUp() thread finishes
    power_up.get()

def __powerDown(self):
    # What to put here?
    pass

def __powerUp(self):
    # What to put here?
    pass

it's slightly different than how you stated it, because first I call powerDown, wait for that to finish, and then call powerUp, but I think it gets the idea done.

Cameron Sparr
  • 3,925
  • 2
  • 22
  • 31
  • What should the initializer and initargs values be for the ThreadPool constructor be? – Chris F Sep 24 '13 at 19:17
  • you don't need to give it anything, but you can give it a processes= argument if need be. Check out the documentation for the ProcessPool constructor, it's exactly the same. – Cameron Sparr Sep 24 '13 at 20:47
  • I did this and it did complain about not having enough parameters passed to the construnctor – Chris F Sep 26 '13 at 16:20