简体   繁体   English

在 Python 完成时终止线程

[英]Terminating a thread on completion in Python

Is there any way to have a thread terminate itself once it is finished its target function?有没有办法让线程在完成其目标 function 后自行终止?

I have an application that requires running a wait for connection function every 2min.我有一个应用程序需要每 2 分钟运行一次等待连接 function。 This function takes around 5 seconds to run.这个 function 运行大约需要 5 秒。

import time
import threading

count = 0 

def fivesecondwait():
    time.sleep(5)
    print("Finished side function")

t = threading.Thread(target = twentysecondwait)

while True:
  if count == 10:
    count = 0
    t.start()

  print("Running Main Application")
  count += 1
  time.sleep(1)

If I try and join the thread the loop stops running, but if I do not include a join it results in the error "Threads can only be started once".如果我尝试加入线程,循环将停止运行,但如果我不包含加入,则会导致错误“线程只能启动一次”。 I need the function to be called every 10 seconds and to not block the execution of the loop.我需要每 10 秒调用一次 function 并且不阻止循环的执行。 So is there any way to have the thread terminate itself so it can be used again?那么有没有办法让线程自行终止以便再次使用它呢?

This is for a measurement device that needs to continue measuring every 50ms while repeatedly waiting for 3-4 seconds for a connection from an MQTT host.这是针对需要每 50 毫秒继续测量一次,同时重复等待 3-4 秒以连接来自 MQTT 主机的测量设备。

Your question and your code don't quite seem to match up, but this much is true;你的问题和你的代码似乎不太匹配,但这是真的; You said, "it results in the error "Threads can only be started once", and your code appears to create a single thread instance, which it then it attempts to start() more than one time.你说, “它会导致错误“线程只能启动一次”,并且你的代码似乎创建了一个thread实例,然后它多次尝试start()

The error message is self explanatory.错误消息是不言自明的。 Python will not allow you to call t.start() more than one time on the same thread instance, t . Python 将不允许您在同一个thread实例t上多次调用t.start() The reason why is, a thread isn't just an object. It's an object that represents an execution of your code (ie, a trip through your code.)原因是,一个thread不仅仅是一个 object。它是一个 object,代表您的代码的执行(即,通过您的代码。)

You can't take the same trip more than one time.您不能多次进行同一次旅行。 Even if you go to the same beach that you visited last year, even if you follow the same route, and stop to rest in all the same places, it's still a different trip.即使你 go 到你去年去过的同一个海滩,即使你走同样的路线,并在所有相同的地方停到 rest,这仍然是一次不同的旅行。 Threads obey the same model.线程遵循相同的 model。

If you want to run twentysecondwait() multiple times "in the background," there's nothing wrong with that, but you'll have to create and start a new thread instance for each execution.如果您想“在后台”多次运行twentysecondwait() ,这没有任何问题,但您必须为每次执行创建并启动一个新的thread实例。


Is there a practical limit to how many thread instances can be created?可以创建多少个线程实例有实际限制吗?

There probably is no practical limit to how many can be sequentially created and destroyed,* but each running thread occupies significant memory and uses other resources as well.对于可以顺序创建和销毁的数量可能没有实际限制,*但每个运行的线程占用大量 memory 并使用其他资源。 So, yes, There is a limit** to how many threads can be "alive" at the same time.所以,是的,有多少线程可以同时“活着”是有限制的。

Your example thread function takes 20 seconds to execute.您的示例线程 function 需要 20 秒才能执行。 If the program starts a new one every ten seconds, then the number of live threads will increase by one every 20 seconds—180 per hour.如果程序每 10 秒启动一个新线程,那么活动线程的数量将每 20 秒增加一个——每小时 180 个。 The program certainly will not be able to sustain that for 90 days.该计划肯定无法维持 90 天。


* A better performing alternative to contually creating and destroying threads is to use a thread pool such as Python's concurrent.futures.ThreadPoolExecutor . * 一个更好的连续创建和销毁线程的替代方法是使用线程池,例如 Python 的concurrent.futures.ThreadPoolExecutor

** The limit is going to depend on what version of Python you are running, on what OS you are running, on how much memory your computer has, etc. The limit probably is not well defined in any case. ** 限制将取决于您正在运行的 Python 的版本、您正在运行的操作系统、您的计算机有多少 memory 等。在任何情况下,该限制可能都没有明确定义。

A thread will automatically terminate itself when it finished running.线程在运行结束后会自动终止。

But:但:

a) you can't start the same thread twice and a)你不能两次启动同一个线程并且

b) you can't re-start a thread that terminated. b) 你不能重新启动一个终止的线程。

Simple solution: always start a new thread.简单的解决方案:始终启动一个新线程。

while True:
  if count == 10:
    count = 0
    t = threading.Thread(target = fivesecondwait)
    t.start()
  ...

[...] so it can be used again? [...] 所以它可以再次使用?

No. You could however keep a single thread running and use synchronization objects to tell the thread when to do something and when not.不,但是您可以保持单个线程运行并使用同步对象来告诉线程何时做某事,何时不做。

This will require more knowledge but be less resource intense.这将需要更多的知识,但资源密集度较低。

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

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