龙空技术网

Python多线程使用技巧(同步 + 异步 + 强制结束多线程)

牛鹭软件测试 318

前言:

此刻姐妹们对“python子线程不阻塞主线程”可能比较看重,小伙伴们都想要学习一些“python子线程不阻塞主线程”的相关内容。那么小编在网络上搜集了一些对于“python子线程不阻塞主线程””的相关文章,希望你们能喜欢,看官们快快来学习一下吧!

多线程同步(函数化)

代码如下:

"""多线程同步(函数化)"""# -*- coding:utf-8 -*-import threadingimport datetimeimport time__author__ = 'Evan'locks = Nonethread_pool = Nonedef unit_test(sleep_time):    """    多线程单元测试    :param sleep_time: 睡眠时间    :return:    """    # locks.acquire()   获取锁 -- 获取锁之后,其他的线程在此等待    with thread_pool:  # 使用线程池控制多线程进入的数量,超过限定数量在此阻塞        print('current thread name {}'.format(threading.current_thread().name))  # 当前线程名        print('{} --> start sleep_time ({})'.format(datetime.datetime.now(), sleep_time))        time.sleep(sleep_time)        print('{} --> sleep_time ({}) finish'.format(datetime.datetime.now(), sleep_time))    # locks.release()   释放锁 -- 如果不释放锁,后续的线程会一直被阻塞不能进入def thread_run(sleep_list):    """    执行多线程    :param sleep_list: 睡眠时间列表    :return:    """    global locks, thread_pool    locks = threading.Lock()  # 线程锁    max_value = 3  # 设置可同时执行的最大线程数为3    thread_pool = threading.Semaphore(value=max_value)  # 初始化线程池    print('线程池最大数量:{}'.format(max_value))    threads = []    for i in sleep_list:  # 配置所有线程        t = threading.Thread(target=unit_test, args=(i,))        threads.append(t)    for thread in threads:  # 开启所有线程        thread.start()        while True:            # 判断正在运行的线程数量, 控制执行的线程数量永远为4-1=3个            if len(threading.enumerate()) <= 4:                # threading.enumerate()包括主线程和所有的活动子线程,长度最少为1                print('剩余活动线程数量: {}'.format(len(threading.enumerate())))                break    # TODO thread.join()和下面的while循环都可阻塞所有线程,依据情况进行选择    # for thread in threads:  # 主线程在此阻塞,等待所有线程结束    #     thread.join()    while True:        # 当线程数量等于1时,并且只剩下一个主线程,退出循环        if len(threading.enumerate()) == 1 and 'MainThread(MainThread' in str(threading.enumerate()[0]):            break    print('所有线程执行结束')def main():    thread_run(sleep_list=[3, 2, 6, 1, 7, 5, 8])if __name__ == '__main__':    main()

执行结果:

线程池最大数量:3current thread name Thread-1剩余活动线程数量: 22020-04-16 17:37:40.504859 --> start sleep_time (3)current thread name Thread-2剩余活动线程数量: 32020-04-16 17:37:40.504859 --> start sleep_time (2)current thread name Thread-3剩余活动线程数量: 42020-04-16 17:37:40.511841 --> start sleep_time (6)2020-04-16 17:37:42.512497 --> sleep_time (2) finish剩余活动线程数量: 4current thread name Thread-42020-04-16 17:37:42.512497 --> start sleep_time (1)2020-04-16 17:37:43.510862 --> sleep_time (3) finish2020-04-16 17:37:43.516815 --> sleep_time (1) finish剩余活动线程数量: 4current thread name Thread-52020-04-16 17:37:43.516815 --> start sleep_time (7)current thread name Thread-6剩余活动线程数量: 42020-04-16 17:37:43.516815 --> start sleep_time (5)2020-04-16 17:37:46.529807 --> sleep_time (6) finishcurrent thread name Thread-72020-04-16 17:37:46.535790 --> start sleep_time (8)剩余活动线程数量: 42020-04-16 17:37:48.523479 --> sleep_time (5) finish2020-04-16 17:37:50.523099 --> sleep_time (7) finish2020-04-16 17:37:54.542362 --> sleep_time (8) finish所有线程执行结束
多线程同步(使用父类继承方法)

代码如下:

"""多线程同步(使用父类继承方法)"""# -*- coding:utf-8 -*-import threadingimport timeimport datetime__author__ = 'Evan'class Test(threading.Thread):  # 继承threading.Thread类    def __init__(self, sleep_time, thread_pool):        super().__init__()  # 执行父类的构造方法        self.sleep_time = sleep_time        self.thread_pool = thread_pool  # 线程池句柄    def run(self):        """        改写父类run方法,需要执行的多线程函数写在这里        :return:        """        print('current thread name {}'.format(threading.current_thread().name))  # 当前线程名        print('{} --> start sleep_time ({})'.format(datetime.datetime.now(), self.sleep_time))        time.sleep(self.sleep_time)        print('{} --> sleep_time ({}) finish'.format(datetime.datetime.now(), self.sleep_time))        self.thread_pool.release()  # 释放线程锁,可用线程数加1if __name__ == '__main__':    max_value = 4    pool = threading.Semaphore(value=max_value)  # 线程池(设置可同时执行的最大线程数为4)    print('线程池最大数量:{}'.format(max_value))    for i in [3, 2, 6, 1, 7]:        pool.acquire()  # 获得线程锁,可用线程数减1        t = Test(sleep_time=i, thread_pool=pool)  # 实例化线程类        t.start()  # 开启线程(线程会自动执行run方法)

执行结果:

线程池最大数量:4current thread name Thread-12020-02-24 12:57:52.198842 --> start sleep_time (3)current thread name Thread-22020-02-24 12:57:52.199840 --> start sleep_time (2)current thread name Thread-32020-02-24 12:57:52.199840 --> start sleep_time (6)current thread name Thread-42020-02-24 12:57:52.199840 --> start sleep_time (1)2020-02-24 12:57:53.200647 --> sleep_time (1) finishcurrent thread name Thread-52020-02-24 12:57:53.202368 --> start sleep_time (7)2020-02-24 12:57:54.200846 --> sleep_time (2) finish2020-02-24 12:57:55.199718 --> sleep_time (3) finish2020-02-24 12:57:58.200735 --> sleep_time (6) finish2020-02-24 12:58:00.202727 --> sleep_time (7) finish
多线程异步

代码如下:

"""多线程异步"""# -*- coding:utf-8 -*-import timeimport datetimefrom concurrent.futures import ThreadPoolExecutor__author__ = 'Evan'def unit_test(sleep_time):    """    多线程单元测试    :param sleep_time: 睡眠时间    :return:    """    print('{} --> start sleep_time ({})'.format(datetime.datetime.now(), sleep_time))    time.sleep(sleep_time)    print('{} --> sleep_time ({}) finish'.format(datetime.datetime.now(), sleep_time))def main():    max_value = 4  # 线程池最大数量    thread_pool = ThreadPoolExecutor(max_workers=max_value)  # 初始化线程池    print('线程池最大数量:{}'.format(max_value))    # 异步多线程运行不会阻塞主线程,异步线程队列满了后会继续往下运行主线程,等队列释放后又回到异步线程继续执行    for i in [3, 2, 6, 1, 7]:        thread_pool.submit(unit_test, i)    print('{} --> 我是主线程'.format(time.ctime()))if __name__ == '__main__':    main()

执行结果:

线程池最大数量:42020-02-24 13:00:35.349155 --> start sleep_time (3)2020-02-24 13:00:35.349155 --> start sleep_time (2)2020-02-24 13:00:35.350151 --> start sleep_time (6)2020-02-24 13:00:35.350151 --> start sleep_time (1)Mon Feb 24 13:00:35 2020 --> 我是主线程2020-02-24 13:00:36.351237 --> sleep_time (1) finish2020-02-24 13:00:36.351237 --> start sleep_time (7)2020-02-24 13:00:37.350428 --> sleep_time (2) finish2020-02-24 13:00:38.350457 --> sleep_time (3) finish2020-02-24 13:00:41.351857 --> sleep_time (6) finish2020-02-24 13:00:43.352244 --> sleep_time (7) finish
强制结束多线程

代码如下:

"""强制结束线程方法:1> 使用stop_thread函数关闭指定的单个线程2> 设置当前函数为守护进程,函数结束后会关闭所有的子线程 --> Set daemon=True"""# -*- coding:utf-8 -*-import threadingimport timeimport inspectimport ctypesdef stop_thread(tid, exctype=SystemExit):    tid = ctypes.c_long(tid.ident)    if not inspect.isclass(exctype):        exctype = type(exctype)    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))    if res == 0:        raise ValueError("Invalid thread id")    elif res != 1:        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)        raise SystemError("PyThreadState_SetAsyncExc failed")def use_stop_thread_function():    def test_1():        while True:            print('-------')            time.sleep(1)    print('Use stop thread function')    t = threading.Thread(target=test_1)    t.start()    time.sleep(5)    stop_thread(tid=t)    print('Threads have been stopped')class UseDaemonFunction(object):    def test_2(self, times):        time.sleep(times)        print('times: {}'.format(times))    def main(self):        # 设置主线程        self.threads = threading.Thread(target=self._main, args=())        self.threads.start()    def _main(self):        print('Use daemon function')        threads = []        for i in range(20):            # 开启20个子线程            t = threading.Thread(target=self.test_2, args=(i, ))            t.daemon = True  # 设置当前函数为守护进程            threads.append(t)        for i in threads:            i.start()        for i in threads:            i.join()        print('Threads have been stopped')if __name__ == "__main__":    # use_stop_thread_function()    # ————分割线————    use_daemon_funcion = UseDaemonFunction()    use_daemon_funcion.main()  # 执行20个子线程    time.sleep(5)    # 杀死主线程,所有的子线程都会被关闭    stop_thread(tid=use_daemon_funcion.threads)    print('All done')

执行结果:

Use daemon functiontimes: 0times: 1times: 2times: 3times: 4All donetimes: 5

标签: #python子线程不阻塞主线程