简体   繁体   English

如何启动和停止线程

[英]How to start and stop a thread

How can I start and stop a thread with my poor thread class?如何使用我糟糕的线程类启动和停止线程?

It is in loop, and 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

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.您实际上不能停止然后重新启动线程,因为在它的run()方法终止后您不能再次调用它的start()方法。 However you can make one pause and then later resume its execution by using a threading.Condition variable to avoid concurrency problems when checking or changing its running state.但是,您可以暂停一次,然后通过使用threading.Condition变量恢复其执行,以避免在检查或更改其运行状态时出现并发问题。

threading.Condition objects have an associated threading.Lock object and methods to wait for it to be released and will notify any waiting threads when that occurs. threading.Condition对象有一个关联的threading.Lock对象和方法来等待它被释放,并在发生时通知任何等待的线程。 Here's an example derived from the code in your question which shows this being done.这是一个从您的问题中的代码派生的示例,它显示了这一点。 In the example code I've made the Condition variable a part of Thread subclass instances to better encapsulate the implementation and avoid needing to introduce additional global variables:在示例代码中,我将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 pause(self):
        with self.state:
            self.paused = True  # Block self.

    def resume(self):
        with self.state:
            self.paused = False
            self.state.notify()  # Unblock self if waiting.


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

    @property
    def elapsed_time(self):
        """ Seconds since started. """
        try:
            return time.time() - self.start_time
        except AttributeError:  # Wasn't explicitly started.
            self.start_time = time.time()
            return 0



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()
    # Can also do other concurrent operations here...
    concur.pause()
    # Do some other stuff...

# Show Concur thread executed.
print('concur.iterations: {}'.format(concur.iterations))

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()

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 documentation for Thread makes 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 .如果要暂停和恢复线程,则需要使用条件变量

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

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