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="")


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM