前言
在Python中,线程(Thread)是比进程更轻量级的执行单位。一个进程可以包含多个线程,它们共享进程的内存空间和资源。Python提供了threading模块来创建和管理线程。
什么是线程
定义
线程是进程中的一个独立执行路径,一个进程可以包含多个线程,它们共享进程的资源和内存空间。
特点
- 共享内存:同一进程中的多个线程共享内存空间和全局变量。
- 更轻量级:相比于进程,线程创建和销毁的开销更小。
- 并发执行:多线程可以在单个CPU上并发执行,或在多核系统上并行执行。
缺点
- Python中存在
GIL
全局解释器锁,这导致在同一个进程里面,同一时刻,只有一个线程在运行,不管你得计算机有多少核,所以Python的多线程,是“伪并行”
线程的使用
Python中,线程使用threading
模块来创建和管理多线程,也可以通过继承Thread
来自定义一个线程类。
import threading
def worker():
print("Worker thread is running")
# 直接创建线程
t = threading.Thread(target=worker)
t.start()
t.join() # 等待线程结束
线程同步
使用Lock来确保多线程对共享资源的访问是安全的。
import threading
lock = threading.Lock()
shared_resource = 0
def worker():
global shared_resource
with lock:
shared_resource += 1
print(shared_resource)
threads = []
for _ in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
for t in threads:
t.join()
线程间通信
可以使用queue.Queue来在线程之间传递数据。
import threading
import queue
def worker(q):
q.put("Data from worker")
q = queue.Queue()
t = threading.Thread(target=worker, args=(q,))
t.start()
print(q.get()) # 从队列中获取数据
t.join()
线程池
Python 3.2+ 提供了concurrent.futures.ThreadPoolExecutor来方便地管理线程池。
from concurrent.futures import ThreadPoolExecutor
def square(x):
return x * x
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(square, [1, 2, 3, 4]))
print(results)
注意事项
- 全局解释器锁(GIL):由于Python的GIL,多线程在CPU密集型任务上并不能真正实现并行,推荐使用多进程。
- 线程安全:需要注意共享资源的访问,确保线程安全。
- 性能问题:在I/O密集型任务中,多线程可以提高性能,比如频繁的文件读写;但在CPU密集型任务中效果有限,比如多路视频流处理。
这些示例和注意事项展示了如何在Python中使用多线程进行并发编程,从而在I/O密集型任务中提高程序的响应能力。
总结
在上面的使用中,不知道你发现没有,Python中线程和进程的使用语法上,基本是一样的,事实上,Python也是尽量保持两者语法上的一致性,到线程和进程是两个不同的概念。
简单记住两点:线程是执行单元
,进程是资源平台
,但这两都是由操作系统来调度
。
简单来说,线程是最终来干活的,所以每一个进程都至少应该用一个主线程。进程就像是一家公司,而线程就是员工,公司提供了各种资源,员工可以共享这些资源,但是员工需要干活。