Python多线程实例详解(python2.7多线程)

liftword3周前 (05-06)技术文章10

以下是一个详细的 Python 多线程实例教程,包含代码逐行解析和应用场景说明:


一、Python 多线程基础

1. 线程 vs 进程

  • 进程:独立内存空间,资源分配的基本单位
  • 线程:共享进程资源,CPU调度的基本单位
  • Python 特性:受 GIL(全局解释器锁)限制,适合 I/O 密集型任务

2. 核心模块

python

import threading

from queue import Queue

import time


二、基础多线程实例

示例1:简单线程创建

python

def print_numbers():

for i in range(5):

time.sleep(1)

print(f"Number: {i}")


def print_letters():

for letter in 'ABCDE':

time.sleep(1)

print(f"Letter: {letter}")


# 创建线程

t1 = threading.Thread(target=print_numbers)

t2 = threading.Thread(target=print_letters)


# 启动线程

t1.start()

t2.start()


# 等待线程结束

t1.join()

t2.join()


print("任务完成!")

输出结果:

复制

Number: 0

Letter: A

Number: 1

Letter: B

Number: 2

Letter: C

...(交替输出)

代码解析:

  1. 定义两个普通函数作为线程任务
  2. 创建 Thread 对象并指定 target
  3. start() 启动线程
  4. join() 等待线程结束

三、线程同步实例

示例2:使用锁防止资源冲突

python

class TicketSystem:

def __init__(self):

self.tickets = 10

self.lock = threading.Lock()


def buy_ticket(self, user):

with self.lock: # 自动获取和释放锁

if self.tickets > 0:

print(f"{user} 买到票!剩余票数:{self.tickets}")

self.tickets -= 1

else:

print(f"{user} 票已售罄!")


def user_action(system, name):

time.sleep(0.1) # 模拟网络延迟

system.buy_ticket(name)


# 创建票务系统

system = TicketSystem()


# 创建10个购票用户

users = [threading.Thread(target=user_action, args=(system, f"用户-{i}"))

for i in range(15)]


# 启动所有线程

for t in users:

t.start()


# 等待所有线程完成

for t in users:

t.join()


print("最终剩余票数:", system.tickets)

输出结果:

复制

用户-0 买到票!剩余票数:10

用户-1 买到票!剩余票数:9

...

用户-9 买到票!剩余票数:1

用户-10 票已售罄!

...

最终剩余票数: 0

关键点:

  • 使用 with 语句自动管理锁
  • 避免多个线程同时修改共享资源
  • 注意锁的粒度控制

四、线程池实践

示例3:使用 concurrent.futures

python

import concurrent.futures

import requests


def download_url(url):

try:

resp = requests.get(url, timeout=3)

return f"{url} 下载完成,状态码:{resp.status_code}"

except Exception as e:

return f"{url} 下载失败:{str(e)}"


urls = [

'https://www.baidu.com',

'https://www.google.com',

'https://www.github.com',

'https://invalid.url'

]


# 创建线程池(最多5个线程)

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:

# 提交任务

future_to_url = {executor.submit(download_url, url): url for url in urls}


# 获取结果

for future in concurrent.futures.as_completed(future_to_url):

url = future_to_url[future]

try:

data = future.result()

except Exception as exc:

print(f'{url} 生成异常: {exc}')

else:

print(data)

输出结果:

复制

https://www.baidu.com 下载完成,状态码:200

https://www.github.com 下载完成,状态码:200

https://invalid.url 下载失败:...

https://www.google.com 下载失败:...

优势:

  • 自动管理线程创建/销毁
  • 方便获取任务结果
  • 支持最大线程数控制

五、生产者-消费者模型

示例4:使用队列实现

python

复制

import random


def producer(queue, name):

for i in range(3):

item = f"产品-{name}-{i}"

time.sleep(random.uniform(0.1, 0.5))

queue.put(item)

print(f"生产 {item}")

queue.put(None) # 结束信号


def consumer(queue):

while True:

item = queue.get()

if item is None:

break

time.sleep(random.uniform(0.2, 0.7))

print(f"消费 {item}")

print("消费者退出")


# 创建队列

q = Queue(5) # 最大容量5


# 创建生产者和消费者

producers = [threading.Thread(target=producer, args=(q, i)) for i in range(2)]

consumers = [threading.Thread(target=consumer, args=(q,)) for _ in range(3)]


# 启动所有线程

for t in producers + consumers:

t.start()


# 等待生产者完成

for t in producers:

t.join()


# 发送结束信号

for _ in consumers:

q.put(None)


# 等待消费者完成

for t in consumers:

t.join()


print("所有任务完成")

输出结果:

复制

生产 产品-0-0

生产 产品-1-0

消费 产品-0-0

生产 产品-0-1

...

消费 产品-1-2

消费者退出

所有任务完成


六、关键知识点总结

  1. 线程创建方式

O 直接实例化 Thread

O 继承 threading.Thread 类

O 使用线程池

  1. 同步机制

O Lock:基础互斥锁

O RLock:可重入锁

O Semaphore:信号量

O Event:事件通知

O Condition:条件变量

  1. 最佳实践

O 优先使用队列进行线程通信

O 避免使用全局变量

O 使用 with 语句管理锁

O 合理设置线程数量

  1. 调试技巧

O 使用 threading.current_thread().name 查看线程信息

O 使用 logging 模块代替 print

O 使用 threading.enumerate() 查看活动线程


七、适用场景建议

  1. 推荐使用

O 网络请求密集型(爬虫、API调用)

O 文件I/O操作

O GUI应用保持响应

O 数据库查询批量处理

  1. 不推荐使用

O CPU密集型计算(推荐使用多进程)

O 需要精确时序控制的任务

O 对线程安全要求极高的场景


通过以上实例,可以系统掌握 Python 多线程的核心用法。实际开发中需注意:虽然多线程可以提高 I/O 密集型任务的效率,但线程数量并非越多越好,通常建议控制在 CPU 核心数 * 5 左右。

相关文章

python 锁Lock功能及多线程程序锁的使用和常见功能示例

锁(Lock)是Python中的一个同步原语,用于线程之间的互斥访问。它可以用来保护共享资源,确保在任意时刻只有一个线程可以访问共享资源,从而避免多线程并发访问引发的数据竞争和不一致性。下面分别详细说...

一文扫盲!Python 多线程的正确打开方式

一、多线程:程序世界的 "多面手"(一)啥是多线程?咱先打个比方,你去餐厅吃饭,一个服务员同时接待好几桌客人,每桌客人就是一个 "线程",服务员同时处理多桌事务就是 &...

python 多线程程序加锁、解锁、锁应用场景示例

锁(Lock)是Python中的一个同步原语,用于线程之间的互斥访问。它可以用来保护共享资源,确保在任意时刻只有一个线程可以访问共享资源,从而避免多线程并发访问引发的数据竞争和不一致性。下面分别详细说...

Python中的“锁”艺术:解锁Lock与RLock的秘密

Python中的“锁”艺术:解锁Lock与RLock的秘密引言随着计算机性能的不断提升以及多核处理器的普及,多线程编程已成为现代软件开发不可或缺的一部分。然而,当多个线程试图同时修改同一份数据时,就可...

24-2-Python多线程-线程操作(python多线程怎么用)

2-线程操作在Python程序中,可以通过“_thread”和“threading(推荐使用)”这两个模块来处理线程。在Python 3程序中,thread模块已废弃。可以使用 threading 模...

Python 如何通过 threading 模块实现多线程。

先熟悉下相关概念多线程是并发编程的一种方式,多线程在 CPU 密集型任务中无法充分利用多核性能,但在 I/O 操作(如文件读写、网络请求)等待期间,线程会释放 GIL,此时其他线程可以运行。GIL是P...