线程
使用thread创建线程
import os, time
from threading import get_native_id, Thread, RLock
def speak(lock):
for index in range(5):
with lock:
print(f'我是{index}正在说话,当前进程是{os.getpid()},线程编号是{get_native_id()}')
time.sleep(1)
def study(lock):
for index in range(5):
with lock:
print(f'我是{index}正在学习,当前进程是{os.getpid()},线程编号是{get_native_id()}')
time.sleep(1)
if __name__ == '__main__':
print(f'-----start-----当前进程是{os.getpid()},线程编号是{get_native_id()}')
# Thread的参数:
# group: 默认值为 None(应当始终为None)
# target: 子线程要执行的可调用对象,默认值为None。
# name: 线程名称,默认为None。如果设置为None,Python会自动分配名字
# args: 给target传的位置参数(元组).
# kwargs:给target 传的关键字参数(字典)
# daemon:标记线程是否为守护线程,取值为布尔值(默认为 None)
lock = RLock()
# 使用 Thread创建线程对象
t1 = Thread(target=speak, args=(lock, ))
t2 = Thread(target=study, args=(lock,))
# 调用线程对象的start方法,会立刻将该线程交由操作系统进行调度
t1.start()
t2.start()
# 让主线程等t1,t2线程执行完毕后,主线程再继续执行
t1.join()
t2.join()
print('-----end-----')
继承thread创建线程
import os, time
from threading import get_native_id, Thread, RLock
class SpeakThread(Thread):
def __init__(self, lock):
super().__init__()
self.lock = lock
def run(self):
for index in range(5):
with self.lock:
print(f'我是{index}正在说话,当前进程是{os.getpid()},线程编号是{get_native_id()}')
time.sleep(1)
class StudyThread(Thread):
def __init__(self, lock):
super().__init__()
self.lock = lock
def run(self):
for index in range(5):
with self.lock:
print(f'我是{index}正在学习,当前进程是{os.getpid()},线程编号是{get_native_id()}')
time.sleep(1)
if __name__ == '__main__':
print(f'-----start-----当前进程是{os.getpid()},线程编号是{get_native_id()}')
lock = RLock()
# 继承 Thread类创建线程对象
t1 = SpeakThread(lock)
t2 = StudyThread(lock)
# 调用线程对象的start方法,会立刻将该线程交由操作系统进行调度
t1.start()
t2.start()
# 让主线程等t1,t2线程执行完毕后,主线程再继续执行
t1.join()
t2.join()
print('-----end-----')
线程池
1、创建线程池执行器,使用 submit 方法提交任务,使用 shutdown 方法等待任务完成
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from threading import get_native_id, RLock
# 1、创建线程池执行器,使用 submit 方法提交任务,使用 shutdown 方法等待任务完成
def work(n, lock):
with lock:
print(f'我是线程{n},我正在工作{get_native_id()}')
time.sleep(1)
if __name__ == '__main__':
print('-----start-----')
# 创建线程池执行器
executor = ThreadPoolExecutor(3)
# 创建线程锁
lock = RLock()
# 使用 submit 方法提交任务(submit 方法是异步的,只负责提交任务,不会阻塞主线程)
executor.submit(work, 1, lock)
executor.submit(work, 2, lock)
executor.submit(work, 3, lock)
executor.submit(work, 4, lock)
executor.submit(work, 5, lock)
executor.submit(work, 6, lock)
executor.submit(work, 7, lock)
# shutdown 方法的作用:不再接收新的任务
# wait=True:阻塞主线程,等待线程池中所有任务执行完毕
executor.shutdown(wait=True)
print('-----end-----')
2 获取子进程执行后的返回结果(Future类的实例对象 + result方法)
def work(n):
print(f'我是线程{n},我正在工作{get_native_id()}')
time.sleep(1)
return f'我是线程{n}的结果'
if __name__ == '__main__':
print('-----start-----')
# 创建线程池执行器
executor = ThreadPoolExecutor(3)
# submit提交任务
features = [executor.submit(work, index) for index in range(1,8)]
# shutdown 阻塞主线程
executor.shutdown(wait=True)
# 打印结果
for f in features:
print(f.result())
print('-----end-----')
3 as_completed 按完成顺序获取结果
def work(n, lock):
with lock:
print(f'我是线程{n},我正在工作{get_native_id()}')
if n == 1:
time.sleep(8)
elif n == 2:
time.sleep(10)
else:
time.sleep(1)
return f'我是线程{n}的结果'
if __name__ == '__main__':
print('-----start-----')
# 创建线程池执行器
executor = ThreadPoolExecutor(3)
# 创建锁
lock = RLock()
# submit提交任务
features = [executor.submit(work, index, lock) for index in range(1,8)]
# 收集每个线程返回的结果
results = []
for f in as_completed(features):
results.append(f.result())
# shutdown 阻塞主线程
executor.shutdown(wait=True)
# 打印结果
print(results)
print('-----end-----')
4 使用 add_done_callback 方法,为任务添加完成时的回调函数