1. 程式人生 > 實用技巧 >threading之執行緒的開始,暫停和退出

threading之執行緒的開始,暫停和退出

目錄

背景

利用多執行緒實現一個開關功能,需要對產生的執行緒進行管理(例如:開啟,暫停,關閉等操作)。

實現程式碼

任務指令碼:

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

"""
@Software: PyCharm
@File: ac_job.py
@Author: 高留柱
@E-mail: [email protected]
@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="")