当前位置: 首页 > news >正文

(19)100天python从入门到拿捏《多线程》

多线程

文章目录

  • 多线程
    • 一、什么是多线程
    • 二、Python 多线程原理
    • 三、创建与启动线程的三种方式
      • 方式 1:直接使用 `threading.Thread`
      • 方式 2:继承 Thread 类
      • 方式 3:使用线程池
    • 四、线程同步与锁机制
    • 五、线程间通信
    • 六、多线程应用场景
    • 七、综合案例:多线程爬取网页标题
    • 八、总结对比

一、什么是多线程

多线程是在同一个进程中同时运行多个线程的技术。
线程是程序中最小的执行单元,一个进程可以包含多个线程,它们共享同一块内存空间。

可以理解为:

进程是“工厂”,线程是“工人”。
多线程就是让多个“工人”同时工作,提高任务的并发性。

二、Python 多线程原理

Python 提供了多线程支持模块

import threading

但是 —— Python有一个重要的机制叫 GIL全局解释器锁

GIL

  • Python在解释器层面同时只能运行一个线程的字节码。
  • 因此多线程无法真正实现并行计算**(在 CPU 密集型任务中无效)。
  • 但在 IO 密集型任务如网络请求、文件读写中,多线程能显著提高性能。

三、创建与启动线程的三种方式

方式 1:直接使用 threading.Thread

import threading
import timedef worker(name):print(f"线程 {name} 开始工作")time.sleep(2)print(f"线程 {name} 结束工作")# 创建线程
t1 = threading.Thread(target=worker, args=("A",))
t2 = threading.Thread(target=worker, args=("B",))# 启动线程
t1.start()
t2.start()# 等待线程结束
t1.join()
t2.join()print("所有线程执行完毕")
线程 A 开始工作
线程 B 开始工作
线程 A 结束工作
线程 B 结束工作
所有线程执行完毕

说明:

  • target:要执行的函数名
  • args:传递给函数的参数(必须是元组)
  • start():启动线程
  • join():等待线程执行完成

方式 2:继承 Thread 类

import threading
import timeclass MyThread(threading.Thread):def __init__(self, name):super().__init__()self.name = namedef run(self):print(f"线程 {self.name} 开始工作")time.sleep(1)print(f"线程 {self.name} 结束工作")# 创建并启动线程
threads = [MyThread(f"Worker-{i}") for i in range(3)]
for t in threads:t.start()
for t in threads:t.join()
线程 Worker-0 开始工作
线程 Worker-1 开始工作
线程 Worker-2 开始工作
线程 Worker-0 结束工作
线程 Worker-2 结束工作
线程 Worker-1 结束工作

适合需要重写逻辑的复杂任务。


方式 3:使用线程池

from concurrent.futures import ThreadPoolExecutor
import timedef task(n):print(f"执行任务 {n}")time.sleep(1)return f"结果 {n}"# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:results = executor.map(task, range(5))for r in results:print(r)
执行任务 0
执行任务 1
执行任务 2
执行任务 3
执行任务 4
结果 0
结果 1
结果 2
结果 3
结果 4

线程池优势:

  • 自动管理线程创建与回收;
  • 支持任务提交、结果收集;
  • 推荐现代项目使用。

四、线程同步与锁机制

由于多个线程共享同一块内存空间,可能同时修改同一变量,造成数据错误。因此需要使用 Lock锁 保护共享资源。

案例:未加锁时数据错误

import threadingx = 0def add():global xfor _ in range(1000000):x += 1t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
t1.start()
t2.start()
t1.join()
t2.join()print("x =", x)  # 理论上应为2000000,但结果往往不对!

加锁后

import threadingx = 0
lock = threading.Lock()def add():global xfor _ in range(1000000):with lock:x += 1t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
t1.start()
t2.start()
t1.join()
t2.join()print("x =", x)  # 结果正确:2000000

五、线程间通信

线程之间不能直接共享变量数据时,可以使用 queue.Queue 实现线程安全通信。

import threading
import queue
import timeq = queue.Queue()def producer():for i in range(5):item = f"任务{i}"print("生产:", item)q.put(item)time.sleep(1)def consumer():while True:item = q.get()if item is None:breakprint("消费:", item)time.sleep(2)# 创建线程
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)t1.start()
t2.start()t1.join()
q.put(None)  # 发送结束信号
t2.join()
生产: 任务0
消费: 任务0
生产: 任务1
消费: 任务1
生产: 任务2
生产: 任务3
消费: 任务2
生产: 任务4
消费: 任务3
消费: 任务4

六、多线程应用场景

场景例子是否推荐
IO密集型文件读写、网络请求、数据库操作✅ 推荐使用
CPU密集型数学计算、图像处理、深度学习❌ 建议使用多进程
并发爬虫同时抓取多个网页✅ 非常常用
实时数据流处理例如日志监听、Socket通信✅ 适用

七、综合案例:多线程爬取网页标题

import threading
import requests
from bs4 import BeautifulSoupurls = ["https://www.python.org/","https://docs.python.org/3/","https://pypi.org/",
]def fetch_title(url):response = requests.get(url)soup = BeautifulSoup(response.text, "html.parser")print(f"{url} 标题:{soup.title.string}")threads = []
for url in urls:t = threading.Thread(target=fetch_title, args=(url,))threads.append(t)t.start()for t in threads:t.join()print("所有网页爬取完毕。")

八、总结对比

特性多线程多进程
共享内存
创建开销
适用任务IO密集CPU密集
典型模块threadingmultiprocessing

python学习专栏导航
(1)100天python从入门到拿捏《Python 3简介》
(2)100天python从入门到拿捏《python应用前景》
(3)100天python从入门到拿捏《数据类型》
(4)100天python从入门到拿捏《运算符》
(5)100天python从入门到拿捏《流程控制语句》
(6)100天python从入门到拿捏《推导式》
(7)100天python从入门到拿捏《迭代器和生成器》
(8)100天python从入门到拿捏《函数和匿名函数》
(9)100天python从入门到拿捏《装饰器》
(10)100天python从入门到拿捏《Python中的数据结构与自定义数据结构》
(11)100天python从入门到拿捏《模块》
(12)100天python从入门到拿捏《文件操作》
(13)100天python从入门到拿捏《目录操作》
(14)100天python从入门到拿捏《Python的错误与异常机制》
(15)100天python从入门到拿捏《面向对象编程》
(16)100天python从入门到拿捏《标准库》
(17)100天python从入门到拿捏《正则表达式》
(18)100天python从入门到拿捏《网络编程》

http://www.dtcms.com/a/477458.html

相关文章:

  • KVM-QEMU 的完整工作流程案例解析
  • 【LeetCode】69. x 的平方根
  • C语言入门教程(第6讲):函数——让程序学会“分工合作”的魔法
  • 福建定制网站开发泰安一级的企业建站公司
  • 公司要建立网站要怎么做太原优化型网站建设
  • 开源 C++ QT QML 开发(十七)进程--LocalSocket
  • 2.CSS3.(3).html
  • 【MQ】RabbitMQ:架构、工作模式、高可用与流程解析
  • 零基础学AI大模型之大模型修复机制:OutputFixingParser解析器
  • 单个服务器部署多个rabbitmq
  • 银行资产管理系统核心业务架构设计
  • 面向快餐店的全程无人化自动化餐厅深度研究方案
  • 开源 C++ QT QML 开发(十八)多媒体--音频播放
  • 【开题答辩全过程】以 宾馆客房管理系统为例,包含答辩的问题和答案
  • 宁波网站建设设计价格我需要做网站
  • 使用 PyTorch 实现 MNIST 手写数字识别
  • ComfyUI安装和启动攻略1
  • h5移动端开发民治网站优化培训
  • uniapp 微信小程序蓝牙接收中文乱码
  • 多制式基站综合测试线的架构与验证实践 (1)
  • Ceph 分布式存储学习笔记(四):文件系统存储管理
  • ceph设置标志位
  • 系统升级丨让VR全景制作更全面、更简单
  • PyTorch 实现 MNIST 手写数字识别全流程
  • PyTorch实现MNIST手写数字识别:从数据到模型全解析
  • PostgreSQL 测试磁盘性能
  • 北京网站开发科技企业网站
  • 干货|腾讯 Linux C/C++ 后端开发岗面试
  • 【深度学习新浪潮】如何入门分布式大模型推理?
  • 基于单片机的螺旋藻生长大棚PH智能控制设计