Python:了解线程和退出线程

时间:2019-03-13 16:31:08

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

谢谢!

2 个答案:

答案 0 :(得分:1)

更新

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

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

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

最后,请注意正确实现join与未实现join但将daemon设置为true之间的区别,尽管两者的行为相似(子线程在存在主线程时停止) 。如果daemon设置为true,则子线程将不会在主线程退出时 wait直到stop (请参见this section中的注释),而在实现join时执行相反。


下面的原始答案

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

例如,将结尾的打印语句替换为:

while True:
    print_time('Main', 3)

答案 1 :(得分:0)

根据我对线程的了解,除非调用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

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

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

了解更多here