繁体   English   中英

Python:了解线程和退出线程

[英]Python: Understanding Threading and Exiting Threads

这是我第一次使用线程。 我想我了解基本知识,但是我不确定退出线程如何工作。

考虑代码:

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循环内只有1个循环之后,代码才会退出。 输出:

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

注意:我不是亲自编写此代码,而是在网上找到了代码并对其进行了调整,以更好地理解线程。

所以我的问题是:

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

谢谢!

UPDATE

原始答案是错误的,因为它错过了@ranjith在评论部分中建议的重要观点。

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

在您的情况下, join是正确实现的,它将self.stoprequest事件设置为true,表示两个子线程停止。 因此,当主线程退出时,两个子线程也退出。

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


下面的原始答案

这是因为您的python程序退出了,因此所有子线程都被隐式杀死。 您需要保持程序运行,才能看到两个子线程继续打印内容。

例如,用下面的内容替换打印语句:

while True:
    print_time('Main', 3)

根据我对线程的了解,它们永远都不应结束,直到调用join()

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

1.在上面的代码中,为什么当从未调用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

在用户决定退出线程程序之前,我将如何使其运行? 我的主要目标是让脚本扫描并分析文件,直到用户告诉它退出为止。

取决于您如何编写目标/可运行方法。 您可以在那里运行永久的逻辑。 将线程视为正在从当前(主)程序中分离出来的一项工作。 您应该将您的任务设计为原子且简单!

在这里阅读更多

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM