开发者

How can I invoke a thread multiple times in Python?

I'm sorry if it is a stupid question. I am trying to use a number of classes of multi-threading to finish different jobs, which involves invoking these multi-threadings at different times for many times. But I am not sure which method to use. The code looks like this:

class workers1(Thread):  
    def __init__(self):  
        Thread.__init__(self)  
    def run(self):  
        do some stuff  

class workers2(Thread):  
    def __init__(self):  
        Thread.__init__(self)  
    def run(self):  
        do some stuff  

class workers3(Thread):  
    def __init__(self):  
        Thread.__init__(self)  
    def run(self):
        do some stuff  

WorkerList1=[workers1(i) for i in range(X)]  
WorkerList2=[workers2(i) for i in range(XX)]  
WorkerList2=[workers3(i) for i in range(XXX)]  


while True:  
    for thread in WorkerList1:  
         thread.run (start? join? or?)
    for thread in WorkerList2:  
          thread.run (start? join? or?)  
    for thread in WorkerList3:  
          thread.run (start? join? or?)  
    do sth  .

I am trying to have all the threads in all the WorkerList to开发者_如何学运维 start functioning at the same time, or at least start around the same time. After sometime once they were all terminated, I would like to invoke all the threads again.

If there were no loop, I can just use .start; but since I can only start a thread once, start apparently does not fit here. If I use run, it seems that all the threads start sequentially, not only the threads in the same list, but also threads from different lists.

Can anyone please help?


there are a lot of misconceptions here:

  • you can only start a specific instance of a thread once. but in your case, the for loop is looping over different instances of a thread, each instance being assigned to the variable thread in the loop, so there is no problem at all in calling the start() method over each thread. (you can think of it as if the variable thread is an alias of the Thread() object instantiated in your list)

  • run() is not the same as join(): calling run() performs as if you were programming sequentially. the run() method does not start a new thread, it simply execute the statements in in the method, as for any other function call.

  • join() does not start executing anything: it only waits for a thread to finish. in order for join() to work properly for a thread, you have to call start() on this thread first.

additionally, you should note that you cannot restart a thread once it has finished execution: you have to recreate the thread object for it to be started again. one workaround to get this working is to call Thread.__init__() at the end of the run() method. however, i would not recommend doing this since this will disallow the use of the join() method to detect the end of execution of the thread.


If you would call thread.start() in the loops, you would actually start every thread only once, because all the entries in your list are distinct thread objects (it does not matter they belong to the same class). You should never call the run() method of a thread directly -- it is meant to be called by the start() method. Calling it directly would not call it in a separate thread.


The code below creates a class that is just a thread but the start and calls the initialization of the Thread class again so that the thread doesn't know it has been called.

from threading import Thread
class MTThread(Thread):
    def __init__(self, name = "", target = None):
        self.mt_name = name
        self.mt_target = target
        Thread.__init__(self, name = name, target = target)
    def start(self):
        super().start()
        Thread.__init__(self, name = self.mt_name, target = self.mt_target)
    def run(self):
        super().run()
        Thread.__init__(self, name = self.mt_name, target = self.mt_target)
def code():
    #Some code
thread = MTThread(name = "SomeThread", target = code)
thread.start()
thread.start()


I had this same dilemma and came up with this solution which has worked perfectly for me. It also allows a thread-killing decorator to be used efficiently.

The key feature is the use of a thread refresher which is instantiated and .started in main. This thread-refreshing thread will run a function that instantiates and starts all other (real, task-performing) threads. Decorating the thread-refreshing function with a thread-killer allows you to kill all threads when a certain condition is met, such as main terminating.

@ThreadKiller(arg) #qu'est-ce que c'est
def RefreshThreads():
    threadTask1 = threading.Thread(name = "Task1", target = Task1, args = (anyArguments))
    threadTask2 = threading.Thread(name = "Task2", target = Task2, args = (anyArguments))
    threadTask1.start()
    threadTask2.start()

#Main
while True:
    #do stuff
    threadRefreshThreads = threading.Thread(name = "RefreshThreads", target = RefreshThreads, args = ())
    threadRefreshThreads.start()


from threading import Thread
from time import sleep
def runA():
    while a==1:
        print('A\n')
        sleep(0.5)

if __name__ == "__main__":
    a=1
    t1 = Thread(target = runA)
    t1.setDaemon(True)
    t1.start()
    sleep(2)
    a=0
    print(" now def runA stops")
    sleep(3)
    print("and now def runA continue")
    a=1
    t1 = Thread(target = runA)
    t1.start()
    sleep(2)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜