zoukankan      html  css  js  c++  java
  • 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="")
    
  • 相关阅读:
    NuGet包介绍
    修改逻辑文件名
    检查扫描文件系统
    C# Newtonsoft.Json不序列字段
    HierarchyId通过父节点创建一个新的子节点
    常用SQL语句
    redis脚本
    asp.net 的一个简单进度条功能
    .Net C#向远程服务器Api上传文件
    使用IKVM在C#中调用JAVA程序
  • 原文地址:https://www.cnblogs.com/cnhyk/p/13697121.html
Copyright © 2011-2022 走看看