Python 如何启动和停止线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15729498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to start and stop thread?
提问by user2229183
Sorry for the old question. I have clarified it. How can I start an stop thread with my poor thread class?
对不起,老问题。我已经澄清了。如何使用我糟糕的线程类启动停止线程?
EDIT: It is in loop, I want to restart it again at the beginning of the code. How can I do start-stop-restart-stop-restart?
编辑:它在循环中,我想在代码的开头再次重新启动它。我该如何开始-停止-重启-停止-重启?
My class:
我的课:
import threading
class Concur(threading.Thread):
def __init__(self):
self.stopped = False
threading.Thread.__init__(self)
def run(self):
i = 0
while not self.stopped:
time.sleep(1)
i = i + 1
In the main code, I want:
在主代码中,我想要:
inst = Concur()
while conditon:
inst.start()
#after some operation
inst.stop()
#some other operation
采纳答案by unutbu
This is David Heffernan's idea fleshed-out. The example below runs for 1 second, then stops for 1 second, then runs for 1 second, and so on.
这是大卫赫弗南的想法充实。下面的示例运行 1 秒,然后停止 1 秒,然后运行 1 秒,依此类推。
import time
import threading
import datetime as DT
import logging
logger = logging.getLogger(__name__)
def worker(cond):
i = 0
while True:
with cond:
cond.wait()
logger.info(i)
time.sleep(0.01)
i += 1
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
cond = threading.Condition()
t = threading.Thread(target=worker, args=(cond, ))
t.daemon = True
t.start()
start = DT.datetime.now()
while True:
now = DT.datetime.now()
if (now-start).total_seconds() > 60: break
if now.second % 2:
with cond:
cond.notify()
回答by David Heffernan
The implementation of stop()would look like this:
的实现stop()如下所示:
def stop(self):
self.stopped = True
If you want to restart, then you can just create a new instance and start that.
如果您想重新启动,那么您可以创建一个新实例并启动它。
while conditon:
inst = Concur()
inst.start()
#after some operation
inst.stop()
#some other operation
The documentationfor Threadmakes it clear that the start()method can only be called once for each instance of the class.
该文档为Thread清楚地表明,该start()方法只能被调用一次为类的每个实例。
If you want to pause and resume a thread, then you'll need to use a condition variable.
如果要暂停和恢复线程,则需要使用条件变量。
回答by martineau
You can't actually stop and then restart a thread since you can't call its start()method again after its run()method has terminated. However you can make one cease and then later resume execution by using a threading.Conditionvariable to avoid concurrency problems when checking or changing its running state.
您实际上无法停止然后重新启动线程,因为start()在其run()方法终止后您无法再次调用其方法。但是,您可以通过使用threading.Condition变量来停止执行,然后在稍后恢复执行,以避免在检查或更改其运行状态时出现并发问题。
threading.Conditionobjects have an associated threading.Lockobject and methods to wait for it to be released and will notify any waiting threads when that occurs. Here's an example derived from the code in your question which shows this being done. In the example code I've made the Conditionvariable a part of Threadsubclass instances to better encapsulate the implementation and avoid needing to introduce additional global variables:
threading.Condition对象有一个关联的threading.Lock对象和方法来等待它被释放,并在发生这种情况时通知任何等待的线程。这是从您的问题中的代码派生的示例,它表明已完成此操作。在示例代码中,我将Condition变量作为Thread子类实例的一部分,以更好地封装实现并避免引入额外的全局变量:
from __future__ import print_function
import threading
import time
class Concur(threading.Thread):
def __init__(self):
super(Concur, self).__init__()
self.iterations = 0
self.daemon = True # Allow main to exit even if still running.
self.paused = True # Start out paused.
self.state = threading.Condition()
def run(self):
self.resume()
while True:
with self.state:
if self.paused:
self.state.wait() # Block execution until notified.
# Do stuff.
time.sleep(.1)
self.iterations += 1
def resume(self):
with self.state:
self.paused = False
self.state.notify() # Unblock self if waiting.
def pause(self):
with self.state:
self.paused = True # Block self.
class Stopwatch(object):
""" Simple class to measure elapsed times. """
def start(self):
""" Establish reference point for elapsed time measurements. """
self.start_time = time.time()
return self.start_time
@property
def elapsed_time(self):
""" Seconds since started. """
try:
start_time = self.start_time
except AttributeError: # Wasn't explicitly started.
start_time = self.start()
return time.time() - start_time
MAX_RUN_TIME = 5 # Seconds.
concur = Concur()
stopwatch = Stopwatch()
print('Running for {} seconds...'.format(MAX_RUN_TIME))
concur.start()
while stopwatch.elapsed_time < MAX_RUN_TIME:
concur.resume()
# ... do some concurrent operations.
concur.pause()
# Do some other stuff...
# Show Concur thread executed.
print('concur.iterations: {}'.format(concur.iterations))

