0

I would like to build a function, which checks if a subthread is already running and if not, start a subthread with any function and paramter given. As multithreading tool I use this post: Is there any way to kill a Thread in Python?

The idea so far is the following:

from ThreadEx import ThreadEx

class MyClass:
    def __init__(self):
        self.__Thread = ThreadEx(name='MyClass',target="")
        self.GlobalVariable = "MyClass Variable"

    def SubThread(self, function): 
        if not self.__Thread.is_alive():
            print("Thread is not alive")
            self.__Thread = ThreadEx(target=function(),args=(self,))
            print("Thread is going to start")
            self.__Thread.start()
            print("Thread started")
        else:
            print("There is already a subthread running")

    def MyFunction1(self, argument1, argument2, argument3):
        self.SubThread(lambda: MyFunction1(self, argument1,argument2,argument3))

    def MyFunction2(self, argument1, argument2):
        self.SubThread(lambda: MyFunction2,argument1,argument2)


def MyFunction1(self, argument1, argument2, argument3):
    print(self.GlobalVariable)
    print("MyFunction1")
    print("Argument1: " + str(argument1))
    print("Argument2: " + str(argument2))
    print("Argument3: " + str(argument3))

def MyFunction2(argument1, argument2):
    print("MyFunction2")
    print("Argument1: " + str(argument1))
    print("Argument2: " + str(argument2))

unfortunately if I execute:

from Myclass import MyClass

self.MyClass = MyClass()
self.MyClass.MyFunction1("Test1","Test2","Test3")

The output is:

Thread is not alive
MyClass Variable
MyFunction1
Argument1: Test1
Argument2: Test2
Argument3: Test3
Thread is going to start
Thread started

So the function is executed before the thread starts. So my question is, how do I send MyFunction including all arguments to a subthread and being able to repeat this with any other function without write a routine each time. I was already looking for *args and **kwargs but I couldn't find the right syntax or it was the wrong way.

Thanks in advance! :)

Community
  • 1
  • 1
Marc
  • 25
  • 4

1 Answers1

0

Your problem is this line:

self.__Thread = ThreadEx(target=function(),args=(self,))

Notice the parentheses behind function. It means not the function is assigned to target, but the result of calling said function. So, the function is executed, it does its printing etc., then its output (None) is assigned to target, and then the thread starts.

Do this instead:

self.__Thread = ThreadEx(target=function,args=(self,))

The more generic alternative to those lambdas is to use *args and **kwargs, as you mention. It should look like this:

class MyClass:
   # ... other class code goes here
   def SubThread(self, function, *args, **kwargs):  # changed
     if not self.__Thread.is_alive():
       print("Thread is not alive")
       self.__Thread = ThreadEx(target=function,args=args, kwargs=kwargs)  # changed
       print("Thread is going to start")
       self.__Thread.start()
       print("Thread started")
     else:
       print("There is already a subthread running")

  def MyFunction1(self, argument1, argument2, argument3):
    self.SubThread(MyFunction1, self, argument1, argument2, argument3)  # changed, note explicit inclusion of self

# ... function code goes here

my_instance = MyClass()
my_instance.MyFunction1("Test1","Test2","Test3")
my_instance.SubThread(MyFunction1, my_instance, "Test1", "Test2", "Test3")  # note explicit inclusion of my_instance
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • Changing to self.__Thread = ThreadEx(target=function,args=(self,)) did not work out, but the generic alternative solves the problem very well! Thanks! – Marc Jul 01 '16 at 11:08