Python并发编程
1、基本概念
1.1、并行与并发
- 并行:同一时间片并列执行
- 并发:不同时间片交替执行
1.2、进程与线程
-
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
-
进程之间不共享全局变量,线程之间共享全局变量(资源竞争问题)
1.3、并发问题解决思路
- 构建队列、缓冲区:挨个执行不要拥挤
- 构建锁:哪个线程抢到独占执行,其它线程等待,该线程执行完成后释放锁
- 预处理:提前加载
- 并行:多核CPU
2、Python中创建线程的3种方式
2.1、线程的状态
我们知道,线程共有5种状态:创建(New)、可运行(Runnable)、阻塞(Blocked)、运行(Running)、终止(Terminated)
通常情况下,线程从运行(Running)到进入阻塞(Blocked)状态有以下情况:
- 睡眠:
sleep()
- 等待:
wait()
,此时需要其他线程通过notify()
方法唤醒 - 同步:
join()
,阻塞主线程,等待子线程结束,即主线程任务结束之前,进入阻塞状态;获取线程锁,但是因为资源已经被其他线程占用时
Python提供的标准模块threading
可用于多线程。Python中创建线程有以下3种方式:
-
函数:使用
threading
模块创建:threading.Thread(func线程函数对象, args传递给线程函数的参数元组类型)
-
继承类:使用
threading
模块创建,继承threading.Thread
类,重写run()
方法 -
线程池:使用
concurrent.futures
模块创建线程池
2.2、函数创建
使用函数创建多线程的步骤如下:
- 定义函数
func(args)
- 创建一个线程:
t=threading.Thread(func, args)
- 启动线程:
t.start()
- 线程阻塞、等待结束:
t.join()
以下是一个示例:
import threading
import time
# 线程执行的函数
def worker(thread_name, delay):
count = 10
while count > 0:
time.sleep(delay)
count -= 1
print(f"{
thread_name} 抢到了,剩余: {
count}")
# 创建2个线程,并开启
thread1 = threading.Thread(target=worker, args=('Thread-1', 1))
thread2 = threading.Thread(target=worker, args=('Thread-2', 2))
thread1.start()
thread2.start()
2.3、继承类创建
可以继承threading.Thread
类,重写run()
方法创建多线程。Thread类提供的方法有:
thread.start()
:启动线程thread.join()
:资源独占,阻塞线程,等待结束(thread占用所有资源,该线程运行完毕后,其他线程才能执行)thread.getName()
:返回线程名thread.setName()
:设置线程名thread.daemon=True/thread.setDaemon(True)
:设置thread线程为主线程的守护线程(会随着主线程的退出而退出,不论该线程是否执行完成)
以下是一个示例:
# Lock对象
lock = threading.Lock()
# 共享资源
count = 10
class MyThread(threading.Thread):
def __init__(self, thread_name, delay):
super(