【问题标题】:Thread that I can pause and resume?我可以暂停和恢复的线程?
【发布时间】:2015-11-10 21:49:36
【问题描述】:

我正在尝试创建一个线程,它在后台执行操作。我需要能够在需要时有效地“暂停”它,并在以后再次“恢复”它。此外,如果当我“暂停”它时线程正在做某事,它应该让调用线程等待,直到它完成它正在做的事情。

我对 Python 中的多线程还很陌生,所以我还没有走那么远。

除了在我的线程正在做某事时调用暂停时让调用线程等待之外,我几乎可以做所有事情。

这是我试图在代码中实现的大纲:

import threading, time

class Me(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        #flag to pause thread
        self.paused = False

    def run(self):
        while True:
            if not self.paused:
                #thread should do the thing if
                #not paused
                print 'do the thing'
                time.sleep(5)

    def pause(self):
        self.paused = True
        #this is should make the calling thread wait if pause() is
        #called while the thread is 'doing the thing', until it is
        #finished 'doing the thing'

    #should just resume the thread
    def resume(self):
        self.paused = False

我想我基本上需要一个锁定机制,但在同一个线程中?

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    Conditions can be used for this.

    这是一个填充骨架的示例:

    class Me(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            #flag to pause thread
            self.paused = False
            # Explicitly using Lock over RLock since the use of self.paused
            # break reentrancy anyway, and I believe using Lock could allow
            # one thread to pause the worker, while another resumes; haven't
            # checked if Condition imposes additional limitations that would 
            # prevent that. In Python 2, use of Lock instead of RLock also
            # boosts performance.
            self.pause_cond = threading.Condition(threading.Lock())
    
        def run(self):
            while True:
                with self.pause_cond:
                    while self.paused:
                        self.pause_cond.wait()
    
                    #thread should do the thing if
                    #not paused
                    print 'do the thing'
                time.sleep(5)
    
        def pause(self):
            self.paused = True
            # If in sleep, we acquire immediately, otherwise we wait for thread
            # to release condition. In race, worker will still see self.paused
            # and begin waiting until it's set back to False
            self.pause_cond.acquire()
    
        #should just resume the thread
        def resume(self):
            self.paused = False
            # Notify so thread will wake after lock released
            self.pause_cond.notify()
            # Now release the lock
            self.pause_cond.release()
    

    希望对您有所帮助。

    【讨论】:

    • 不幸的是,恢复功能似乎不起作用。不通知 - 通知线程?所以线程正在通知自己没有做任何事情?也许我的理解是错误的? :)
    • @mickzer:你不会从正在工作的同一个线程调用pauseresume;如果线程被阻塞等待条件,它不会做任何其他事情。线程的run 是唯一实际在指定线程中运行的东西,另一个线程正在暂停(等待工作线程真正空闲),并在稍后恢复。
    • 我的错,这行 self.pause_cond.release() 被 stackoverflow 隐藏了 -
       元素没有滚动。我的道歉 - 和很棒的答案
    • 以下 mguijarr 的 IMO 回答,它使用事件而不是条件更适合此目的。
    • @ShadowRanger 如果多个线程同时运行“run”函数,只有 1 个线程会打印 'do the thing' 而其他线程等待。这是正确的吗?
    【解决方案2】:

    使用threading.Event 代替布尔变量,并为忙碌状态添加另一个事件:

    def __init__(self):
        ...
        self.can_run = threading.Event()
        self.thing_done = threading.Event()
        self.thing_done.set()
        self.can_run.set()    
    
    def run(self):
        while True:
            self.can_run.wait()
            try:
                self.thing_done.clear()
                print 'do the thing'
            finally:
                self.thing_done.set()
    
    def pause(self):
        self.can_run.clear()
        self.thing_done.wait()
    
    def resume(self):
        self.can_run.set()
    

    编辑:之前的回答是错误的,我已修复并更改了变量名以明确

    【讨论】:

    • 如果我必须在 print('do the thing') 之后立即暂停,以便其他线程启动然后恢复该线程?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    相关资源
    最近更新 更多