使用包括参数的任意函数启动子线程

时间:2016-06-30 19:14:04

标签: python multithreading parameter-passing

我想构建一个函数,它检查子线程是否已在运行,如果没有,则启动一个带有任何函数和参数的子线程。作为多线程工具,我使用这篇文章:Is there any way to kill a Thread in Python?

到目前为止的想法如下:

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))
不幸的是,如果我执行:

from Myclass import MyClass

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

输出结果为:

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

因此该函数在线程启动之前执行。所以我的问题是,我如何发送MyFunction包括所有参数到子线程,并且能够在没有每次编写例程的情况下使用任何其他函数重复此操作。 我一直在寻找* args和** kwargs,但我找不到正确的语法或者它是错误的方法。

提前致谢! :)

1 个答案:

答案 0 :(得分:0)

你的问题就在这一行:

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

注意函数后面的括号。这意味着不是将功能分配给目标,而是调用所述功能的结果。因此,函数执行,它执行打印等,然后将其输出(None)分配给target,然后线程启动。

请改为:

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

正如您所提到的,对这些lambdas的更通用的替代方法是使用*args**kwargs。它应该是这样的:

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