Python:理解线程和退出线程

Python:理解线程和退出线程,python,multithreading,Python,Multithreading,这是我第一次使用线程。我想我理解基本原理,但我不确定现有线程是如何工作的 以代码为例: class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter self.st

这是我第一次使用线程。我想我理解基本原理,但我不确定现有线程是如何工作的

以代码为例:

class myThread (threading.Thread):
  def __init__(self, threadID, name, counter):
    threading.Thread.__init__(self)
    self.threadID = threadID
    self.name = name
    self.counter = counter
    self.stoprequest=threading.Event()
  def run(self):
    while not self.stoprequest.isSet():
      print("Starting " + self.name)
      print_time(self.name,self.counter)
      print("Exiting " + self.name)

  def join(self, timeout=None):
    self.stoprequest.set()
    super(myThread,self).join(timeout)

def print_time(threadName, delay):
  time.sleep(delay)
  print("%s: %s" % (threadName, time.ctime(time.time())))


thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()

print("Exiting Main Thread")
从我对线程的理解来看,在调用join之前,它们永远不会结束,但是每个线程的while循环中只有一个周期之后,代码才会退出。输出:

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Wed Mar 13 09:13:32 2019
Exiting Thread-1
Thread-2: Wed Mar 13 09:13:33 2019
Exiting Thread-2
注意:我并不是自己写这段代码的,我在网上找到了这段代码,并对其进行了调整,试图更好地理解线程

所以我的问题是:

在上面的代码中,当从未调用join时,为什么线程只执行while循环的一个周期?我希望这些线索永远不会结束。 在用户决定退出线程程序之前,我如何让它运行?我的主要目标是让脚本扫描和分析文件,直到用户告诉它退出。 谢谢

更新

最初的答案是错误的,因为它遗漏了@ranjith在评论部分提出的一个要点

如果删除myThread定义中的join函数,您将发现程序不会退出,正如@ranjith所提到的。原因是,当主线程存在时,它会自动在其所有非守护进程线程上调用join,如中所示。如果您从未为myThread类实现join,那么调用join将立即返回,而不会终止子线程

在您的例子中,正确实现了join,这将self.stoprequest事件设置为true,并向两个子线程发出停止的信号。因此,当主线程退出时,两个子线程也会退出

最后,请注意正确实现join与不实现join但将daemon设置为true之间的区别,尽管它们的行为类似,但子线程在主线程存在时停止。如果daemon设置为true,则在主线程退出时,子线程不会等待直到停止(请参见中的说明),而实现join则会执行相反的操作

原始答案如下

这是因为python程序退出,所以所有子线程都被隐式终止。您需要保持程序运行,以便看到两个子线程继续打印内容

例如,将末尾的print语句替换为:

while True:
    print_time('Main', 3)
从我对线程的理解来看,在调用join之前,它们永远不会结束

事实并非如此。这完全取决于如何实现在线程中运行的任务。通过重写Thread类的run方法或提供可调用的任务,例如将在Thread的run方法中调用的函数作为目标。当任务终止或出现某种异常时,线程结束。 线程上的join方法实际上是等待线程终止。您还可以只提供特定时间的超时等待

一,。在上面的代码中,当从未调用join时,为什么线程只执行while循环的一个周期?我希望这些线索永远不会结束

你怎么知道它执行一个周期?使用您的代码,我的任务将永远运行 我的产出

Starting Thread-2
Thread-1: Wed Mar 13 12:03:42 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:43 2019
Exiting Thread-1
Starting Thread-1
Thread-2: Wed Mar 13 12:03:44 2019
Exiting Thread-2
Starting Thread-2
Thread-1: Wed Mar 13 12:03:44 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:46 2019
Exiting Thread-1
Starting Thread-1
#and goes on
在用户决定退出线程程序之前,我如何让它运行?我的主要目标是让脚本扫描和分析文件,直到用户告诉它退出

取决于如何编写目标/可运行方法。你可以在那里永远运行逻辑。把线程看作是从当前主程序中分离出来的一部分工作。你应该把你的任务设计成原子的和简单的


阅读更多内容

我觉得退出主线程的输出行可疑。这条主线是从哪里开始的?很抱歉,我在粘贴时漏掉了一行。已经更新了,谢谢!我知道您的while循环将是infinte,那么使用self.stoprequest条件有什么意义呢?我的理解是,虽然self.stoprequest.isSet:不是保持线程运行的无限循环,但不确定这是真的。如果一个线程被标记为守护进程,那么它将与主线程一起退出thread@helloworld95用于停止单个线程的。例如,主线程可以调用thread1.join来停止thread1,同时保持thread2运行。如果从未调用该函数,那么如果主线程退出,则所有线程都将退出。@ranjith我想你说的是相反的。如果一个线程被标记为守护进程,那么即使主线程退出,该线程也不会自动终止。这是一种特殊情况,但值得一提。不,我认为是相反的:我自己做了一些实验来证明这一点,这是我的观察结果。如果一个线程被标记为守护进程,那么基本上您不必专门等待它完成。它在主线程和其他非守护进程线程退出时完成。对于非守护进程线程,即使您退出main,这些线程也会继续执行,直到它们完成/异常