如何在Python中多次调用线程?

7 投票
5 回答
30343 浏览
提问于 2025-04-16 06:43

抱歉如果这个问题听起来有些傻。我正在尝试使用多线程的几个类来完成不同的任务,这些任务需要在不同的时间多次调用这些多线程。不过,我不太确定该用什么方法。我的代码大致是这样的:

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  .

我想让所有的WorkerList中的线程同时开始工作,或者至少在差不多的时间开始。过一段时间后,当它们都结束时,我想再次调用所有的线程。

如果没有循环的话,我可以直接用.start;但是因为每个线程只能启动一次,所以.start显然不适合这里。如果我用.run,似乎所有的线程都是一个接一个地启动,不仅是同一个列表中的线程,其他列表中的线程也是如此。

有没有人能帮帮我呢?

5 个回答

2

下面的代码创建了一个类,这个类实际上就是一个线程。不过,它在启动时又重新调用了线程类的初始化,这样线程就不知道自己被调用过了。

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()
2

如果你在循环中调用 thread.start(),你其实只会启动每个线程一次,因为你列表里的每个条目都是不同的线程对象(它们属于同一个类也没关系)。你绝对不应该直接调用线程的 run() 方法——这个方法是应该通过 start() 方法来调用的。直接调用的话,就不会在一个单独的线程中运行。

13

这里有很多误解:

  • 你只能启动一个线程的特定实例一次。但在你的例子中,for 循环是遍历不同的线程实例,每个实例在循环中都被分配给变量 thread,所以对每个线程调用 start() 方法完全没有问题。(你可以把变量 thread 想象成你列表中每个 Thread() 对象的别名)

  • run()join() 是不一样的:调用 run() 的效果就像你在顺序编程。run() 方法并不会启动一个新线程,它只是执行方法中的语句,就像调用其他函数一样。

  • join() 并不会开始执行任何东西:它只是等待一个线程完成。要让 join() 正常工作,你必须先对这个线程调用 start()

另外,你需要注意的是,一旦线程执行完毕,你不能重新启动它:你必须重新创建线程对象才能再次启动。一个解决方法是在 run() 方法的末尾调用 Thread.__init__()。不过,我不推荐这样做,因为这会导致你无法使用 join() 方法来检测线程的执行结束。

撰写回答