Loading

threading之线程的开始,暂停和退出

背景

利用多线程实现一个开关功能,需要对产生的线程进行管理(例如:开启,暂停,关闭等操作)。

实现代码

任务脚本:

#!/usr/bin/python3
# _*_ coding: utf-8 _*_

"""
@Software: PyCharm
@File: ac_job.py
@Author: 高留柱
@E-mail: liuzhu.gao@foxmail.com
@Time: 2020/9/19 10:30 上午
@Notes: 用于开启线程,执行ac_work中的任务
"""
import threading
from utils.hfac_lib import hfac_work


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后返回
            try:
                # 任务
                hfac_work.start_ac()
            except Exception as e:
                # 如果任务失败,自动结束该线程,外层可用方法判断线程是否存活,从而判断任务是否失败。
                # return 方法在线程中不能使用
                self.stop()
                print(e)

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

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

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

调用脚本:
方法:

  • job.start() 启动线程
  • job.stop() 停止线程
  • job.pause() 暂停线程
  • job.resume() 恢复线程
  • job.is_alive() 判断线程是否存活

无论是暂停还是停止, 都不是瞬时的, 必须等待run函数内部的运行到达标志位判断时才有效. 也就是说操作会滞后一次.
因此,在主进程中停止线程的任务,在使用is_alive()方法之前最好加上个time.sleep(),防止线程滞后,导致is_alive()方法失败

    def post(self, request, *args, **kwargs):
        """
        开始和停止测试(控制电源硬件)
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        global job, is_start
        is_run = request.POST.get("is_run")
        if not job:
            job = ac_job.Job()
        if is_run == "1":
            if not is_start:
                job.start()
                # 此处time.sleep一会儿,如果线程中出现异常会调用self.stop,延迟一会儿,方便线程终止后判断是否存活线程
                # 如果不延迟一会儿,主进程检测是否存活的时候,线程还没死掉
                time.sleep(3)
                if not job.is_alive():
                    return APIResponse(1, "程序开始失败,请检查电源的com口是否异常!", result="")
                is_start = True
                return APIResponse(msg="开始测试!", result="")
            return APIResponse(1, "程序已经在测试中,需要先停止!", result="")
        else:
            if is_start:
                job.stop()
                job = None
                is_start = False
                return APIResponse(msg="测试已停止!", result="")
            return APIResponse(1, "程序没有在测试中,无法停止!", result="")
posted @ 2020-09-19 18:10  开花的马铃薯  阅读(4614)  评论(0编辑  收藏  举报