文章目录
- 多线程同步(函数化)
- 多线程同步(使用父类继承方法)
- 多线程异步
- 强制结束多线程
多线程同步(函数化)
代码如下:
"""
多线程同步(函数化)
"""
# -*- coding:utf-8 -*-
import threading
import datetime
import time
__author__ = 'Evan'
locks = None
thread_pool = None
def 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()
执行结果:
线程池最大数量:3
current thread name Thread-1剩余活动线程数量: 2
2020-04-16 17:37:40.504859 --> start sleep_time (3)
current thread name Thread-2剩余活动线程数量: 3
2020-04-16 17:37:40.504859 --> start sleep_time (2)
current thread name Thread-3剩余活动线程数量: 4
2020-04-16 17:37:40.511841 --> start sleep_time (6)
2020-04-16 17:37:42.512497 --> sleep_time (2) finish
剩余活动线程数量: 4
current thread name Thread-4
2020-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
剩余活动线程数量: 4
current thread name Thread-5
2020-04-16 17:37:43.516815 --> start sleep_time (7)
current thread name Thread-6
剩余活动线程数量: 4
2020-04-16 17:37:43.516815 --> start sleep_time (5)
2020-04-16 17:37:46.529807 --> sleep_time (6) finish
current thread name Thread-7
2020-04-16 17:37:46.535790 --> start sleep_time (8)
剩余活动线程数量: 4
2020-04-16 17:37:48.523479 --> sleep_time (5) finish
2020-04-16 17:37:50.523099 --> sleep_time (7) finish
2020-04-16 17:37:54.542362 --> sleep_time (8) finish
所有线程执行结束
多线程同步(使用父类继承方法)
代码如下:
"""
多线程同步(使用父类继承方法)
"""
# -*- coding:utf-8 -*-
import threading
import time
import 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() # 释放线程锁,可用线程数加1
if __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方法)
执行结果:
线程池最大数量:4
current thread name Thread-1
2020-02-24 12:57:52.198842 --> start sleep_time (3)
current thread name Thread-2
2020-02-24 12:57:52.199840 --> start sleep_time (2)
current thread name Thread-3
2020-02-24 12:57:52.199840 --> start sleep_time (6)
current thread name Thread-4
2020-02-24 12:57:52.199840 --> start sleep_time (1)
2020-02-24 12:57:53.200647 --> sleep_time (1) finish
current thread name Thread-5
2020-02-24 12:57:53.202368 --> start sleep_time (7)
2020-02-24 12:57:54.200846 --> sleep_time (2) finish
2020-02-24 12:57:55.199718 --> sleep_time (3) finish
2020-02-24 12:57:58.200735 --> sleep_time (6) finish
2020-02-24 12:58:00.202727 --> sleep_time (7) finish
多线程异步
代码如下:
"""
多线程异步
"""
# -*- coding:utf-8 -*-
import time
import datetime
from 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()
执行结果:
线程池最大数量:4
2020-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) finish
2020-02-24 13:00:36.351237 --> start sleep_time (7)
2020-02-24 13:00:37.350428 --> sleep_time (2) finish
2020-02-24 13:00:38.350457 --> sleep_time (3) finish
2020-02-24 13:00:41.351857 --> sleep_time (6) finish
2020-02-24 13:00:43.352244 --> sleep_time (7) finish
强制结束多线程
代码如下:
"""
强制结束线程方法:
1> 使用stop_thread函数关闭指定的单个线程
2> 设置当前函数为守护进程,函数结束后会关闭所有的子线程 --> Set daemon=True
"""
# -*- coding:utf-8 -*-
import threading
import time
import inspect
import ctypes
def 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 function
times: 0
times: 1
times: 2
times: 3
times: 4
All done
times: 5
Over~