Python关于Threading暂停恢复解决办法

我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦start后, 线程就属于失控状态. 不过, 我们可以自己实现这些. 一般的方法就是循环地判断一个标志位, 一旦标志位到达到预定的值, 就退出循环. 这样就能做到退出线程了. 但暂停和恢复线程就有点难了, 我一直也不清除有什么好的方法, 直到我看到threading中Event对象的wait方法的描述时.

复制代码
wait([timeout])

    Block until the internal flag is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.

    阻塞, 直到内部的标志位为True时. 如果在内部的标志位在进入时为True时, 立即返回. 否则, 阻塞直到其他线程调用set()方法将标准位设为True, 或者到达了可选的timeout时间.


    When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof).

    This method returns the internal flag on exit, so it will always return True except if a timeout is given and the operation times out.

    当给定了timeout参数且不为None, 它应该是一个浮点数,以秒为单位指定操作的超时(或是分数)。

    此方法在退出时返回内部标志,因此除非给定了超时且操作超时,否则它将始终返回True。


    Changed in version 2.7: Previously, the method always returned None.

    2.7版本以前, 这个方法总会返回None.
复制代码

 

 

  利用wait的阻塞机制, 就能够实现暂停和恢复了, 再配合循环判断标识位, 就能实现退出了, 下面是代码示例:

 

复制代码
#!/usr/bin/env python
# coding: utf-8

import threading
import time


class Job(threading.Thread):

    def __init__(self, *args, **kwargs):
        super(Job, self).__init__(*args, **kwargs)
        self.__flag = threading.Event()     # 用于暂停线程的标识
        self.__flag.set()       # 设置为True
        self.__running = threading.Event()      # 用于停止线程的标识
        self.__running.set()      # 将running设置为True

    def run(self):
        while self.__running.isSet():
            self.__flag.wait()      # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
            print time.time()
            time.sleep(1)

    def pause(self):
        self.__flag.clear()     # 设置为False, 让线程阻塞

    def resume(self):
        self.__flag.set()    # 设置为True, 让线程停止阻塞

    def stop(self):
        self.__flag.set()       # 将线程从暂停状态恢复, 如何已经暂停的话
        self.__running.clear()        # 设置为False    
复制代码

 

下面是测试代码:

复制代码
a = Job()
a.start()
time.sleep(3)
a.pause()
time.sleep(3)
a.resume()
time.sleep(3)
a.pause()
time.sleep(2)
a.stop()
复制代码

 

测试的结果:

 

 

  这完成了暂停, 恢复和停止的功能. 但是这里有一个缺点: 无论是暂停还是停止, 都不是瞬时的, 必须等待run函数内部的运行到达标志位判断时才有效. 也就是说操作会滞后一次.

  但是这有时也不一定是坏事. 如果run函数中涉及了文件操作或数据库操作等, 完整地运行一次后再退出, 反而能够执行剩余的资源释放操作的代码(例如各种close). 不会出现程序的文件操作符超出上限, 数据库连接未释放等尴尬的情况.

转载于:https://www.cnblogs.com/0xHack/p/9401717.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 中,可以使用 `threading` 模块来创建和管理线程。要暂停恢复线程的执行,可以使用 `threading.Event` 对象来实现。`Event` 对象有两个方法 `set()` 和 `clear()`,分别用于设置和清除标志位,可以通过 `wait()` 方法来阻塞线程,直到标志位被设置。 以下是示例代码: ```python import threading import time # 创建 Event 对象 pause_event = threading.Event() def worker(): while True: # 等待标志位被设置 pause_event.wait() print("Working...") time.sleep(1) # 创建线程并启动 t = threading.Thread(target=worker) t.start() while True: cmd = input("Enter command (pause/resume/exit): ") if cmd == "pause": # 清除标志位,暂停线程 pause_event.clear() print("Thread paused.") elif cmd == "resume": # 设置标志位,恢复线程 pause_event.set() print("Thread resumed.") elif cmd == "exit": # 结束线程并退出程序 t.join() break ``` 在上面的代码中,我们创建了一个 `worker` 函数,用于模拟线程的工作。在工作循环中,我们使用 `pause_event.wait()` 方法来等待标志位被设置,如果标志位被清除,则线程会被暂停。 在主线程中,我们使用一个无限循环来读取用户输入的命令,并根据命令设置或清除标志位。如果输入 "pause",则清除标志位,暂停线程;如果输入 "resume",则设置标志位,恢复线程;如果输入 "exit",则结束线程并退出程序。 需要注意的是,在线程被暂停时,可能会导致资源没有被正确释放。因此,在实际应用中,需要根据具体情况选择合适的暂停方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值