并发模型
多线程:多个线程在同一进程中并发执行(threading)
每个进程都有一个全局解释器锁,由于全局解释器锁(GIL)的存在,同一时刻只有一个线程执行Python字节码,限制了多核处理器的利用。
多线程适用于IO密集型任务如网络请求文件读写等,而计算密集型无法充分利用多核处理器
多进程(multiprocessing)
每个进程有自己的内存空间,进程之间通信需要通过特殊的机制,如队列、管道等
多进程克服了GIL的限制,多个进程并发执行Python字节码,在处理计算密集型任务是有优势,如科学计算、图像处理等
混合编程
多线程的创建
Thread类
通过传递函数创建,考察以下代码:
import time
from threading import Thread
# 自定义线程函数。
def target(name="Python"):
for i in range(2):
print("hello", name)
time.sleep(1)
# 创建线程01,不指定参数
thread_01 = Thread(target=target, args=("MING",))
# 启动线程01
thread_01.start()
继承类创建,考察以下代码:
import time
from threading import Thread
class MyThread(Thread):
def __init__(self, type="Python"):
# 注意:super().__init__() 必须写
# 且最好写在第一行
super().__init__()
self.type=type
def run(self):
for i in range(2):
print("hello", self.type)
time.sleep(1)
if __name__ == '__main__':
# 创建线程01,不指定参数
thread_01 = MyThread()
# 创建线程02,指定参数
thread_02 = MyThread("MING")
thread_01.start()
thread_02.start()
使用 concurrent.futures
模块线程池创建
from concurrent.futures import ThreadPoolExecutor
# 使用 ThreadPoolExecutor 创建线程池中的线程
with ThreadPoolExecutor() as executor:
future = executor.submit(my_function)
使用 queue
模块自定义线程池创建线程
线程常用函数
# 如上所述,创建一个线程
t=Thread(target=func)
# 启动子线程
t.start()
# 等待线程 t 结束
t.join()
# 判断线程是否在执行状态,在执行返回True,否则返回False
t.is_alive()
t.isAlive()
# 设置线程 t 是否为守护线程,默认为False
# 守护线程会在主线程退出时自动退出,不管它是否完成执行
t.daemon = True
t.daemon = False
# 设置线程名
t.name = "My-Thread"
Python的几种锁
互斥锁和递归锁和信号量和事件
import threading
lock = threading.Lock()
rlock = threading.RLock()
semaphore = threading.Semaphore(2) # 允许两个线程同时访问
event = threading.Event()