Python多线程示例

# -*- coding: utf-8 -*-
import ctypes
import sys
import threading
import time


class _MyThread(threading.Thread):
    def __init__(self, target=None, args=(), kwargs=None, daemon=True):
        super(_MyThread, self).__init__(target=target, args=args, kwargs=kwargs, daemon=daemon)
        self.flag = threading.Event()

    # 虽然能停止线,会有不可预知的问题
    def stop(self):
        print(f"停止线程 {self.name}")
        if not self.is_alive():
            return
        exc = ctypes.py_object(SystemExit)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
            ctypes.c_long(self.ident), exc)
        if res == 0:
            raise ValueError("找不到线程ID")
        elif res > 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident, None)
            raise SystemError("线程已停止")


class MyThread(threading.Thread):
    dict_ = [{"kill": False} for i in range(1000)]

    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, daemon=True, dict_={}):
        threading.Thread.__init__(self, group=group, target=target, name=name,
                                  args=args, kwargs=kwargs, daemon=daemon)
        if dict_:
            self.killed = dict_
        else:
            self.killed = {"kill": False}

    def start(self):
        print(f"开启线程{self}")
        self.__run_backup = self.run
        self.run = self.__run
        threading.Thread.start(self)

    def __run(self):
        sys.settrace(self.globaltrace)
        self.__run_backup()
        self.run = self.__run_backup

    def globaltrace(self, frame, event, arg):
        if event == 'call':
            return self.localtrace
        else:
            return None

    def localtrace(self, frame, event, arg):
        if self.killed["kill"]:
            if event == 'line':
                if self.killed["kill"] == 1:
                    raise SystemExit()
                elif self.killed["kill"] == 2:
                    while self.killed["kill"]:
                        time.sleep(0.1)
        return self.localtrace

    def stop(self):
        print(f"停止线程{self}")
        self.killed["kill"] = 1

    def pause(self):
        print(f"暂停线程{self}")
        self.killed["kill"] = 2

    def resume(self):
        print(f"恢复线程{self}")
        self.killed["kill"] = False


def test_func(num):
    for i in range(num):
        time.sleep(1)
        print(i)


if __name__ == '__main__':
    # 第一种线程
    # t = _MyThread(target=test_func,args=(100,))
    # t.start()
    # time.sleep(5)
    # t.stop()
    # input()
    # # 第二种线程
    t = MyThread(target=test_func, args=(100,))
    t.start()
    time.sleep(3)
    t.pause()
    time.sleep(3)
    t.resume()
    time.sleep(3)
    t.stop()
    input()