首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Python中实现守护进程可停止轮询线程?

如何在Python中实现守护进程可停止轮询线程?
EN

Stack Overflow用户
提问于 2015-10-27 10:37:49
回答 1查看 2.6K关注 0票数 0

据我理解,python中没有这样的开箱即用解决方案。

该解决方案必须具有以下特点:

  • 使用目标函数和可选参数将线程作为守护进程启动。
  • 有轮询:线程应该每X秒重新运行目标
  • 让轻松优雅的停下来:中途不打破目标执行。
  • 公开从它所属的程序外部停止的能力,特别是能够阻止线程测试代码。
  • 允许线程在停止后重新启动(或使用新线程伪重新启动)

我在这方面遇到了几个建议,但我想在这里汇总所有收集到的知识(我将在后续答复中对此作出贡献),以便听取任何新的或替代的或更多的想法。

EN

回答 1

Stack Overflow用户

发布于 2015-10-27 10:37:49

我的建议使用threading库,因为它被宣传为比thread更高的级别。

一个中间点是这个解决方案,从其他的答案中找到:

代码语言:javascript
复制
def main():
   t_stop= threading.Event()
   t = threading.Thread(target=thread, args=(1, t_stop))
   t.daemon = True
   t.start()

   time.sleep(duration)
   #stop the thread
   t_stop.set()

def thread(arg, stop_event):
    while(not stop_event.is_set()):
        # Code to execute here
        stop_event.wait(time)

不幸的是,这要求我们在测试停止线程的t_stop顺序时方便地使用-in对象,而对象的句柄并不是设计为公开的。

一个解决方案是在顶级或全局字典中添加tt_stop句柄,以便达到测试代码的要求。

另一种解决方案(从某处复制和改进)是使用以下方法:

代码语言:javascript
复制
def main():
    t = DaemonStoppableThread(sleep_time, target=target_function,
                              name='polling_thread',
                              args=(arg1, arg2))
    t.start()

# Stopping code from a test
def stop_polling_threads():
    threads = threading.enumerate()
    polling_threads = [thread for thread in threads
                       if 'polling_thread' in thread.getName()]
    for poll_thread in polling_threads:
        poll_thread.stop()


class DaemonStoppableThread(threading.Thread):

    def __init__(self, sleep_time, target=None,  **kwargs):
        super(DaemonStoppableThread, self).__init__(target=target, **kwargs)
        self.setDaemon(True)
        self.stop_event = threading.Event()
        self.sleep_time = sleep_time
        self.target = target

    def stop(self):
        self.stop_event.set()

    def stopped(self):
        return self.stop_event.isSet()

    def run(self):
        while not self.stopped():
            if self.target:
                self.target()
            else:
                raise Exception('No target function given')
            self.stop_event.wait(self.sleep_time)

尽管这些解决方案可能是好的,但它们中没有一个面临轮询目标函数的重新启动。

我避免使用表达式“重新启动线程”,因为我理解python线程不能重新启动,因此必须使用一个新线程来允许这种“伪重新启动”。

编辑:

为了改进上面的内容,一个多次启动/停止轮询目标的解决方案:

代码语言:javascript
复制
class ThreadManager(object):
    def __init__(self):
       self.thread = None

    def start_thread(self):
        if not self.thread or not self.thread.is_alive():
            self.thread = DaemonStoppableThread(sleep_time=5, target=some_func, args=(1, 2))
            self.thread.start()
        return 'thread running'

    def stop_thread(self):
        if self.thread and self.thread.is_alive():
            self.thread.stop()
            return 'thread stopped'
        else:
            return 'dead thread'

    def check_thread(self):
        if self.thread and self.thread.is_alive():
            return 'thread alive'
        else:
            return 'dead_thread'
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33365664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档