掌握Python多线程,这些技巧你必须知道!

news2024/11/17 7:51:15

47e352ac371421e762b08fdd0729e800.png

更多Python学习内容:ipengtao.com

多线程是一种能够并发执行代码的方法,可以提高程序的执行效率和响应速度。本文将详细介绍 Python 中多线程的概念、使用场景、基本用法以及实际应用,可以更好地掌握多线程编程。

什么是多线程?

多线程是一种在单个进程内并发执行多个线程的技术。每个线程共享相同的内存空间,可以并行执行任务。多线程的主要目的是提高程序的并发性,从而提升执行效率。

多线程的使用场景

  1. I/O 密集型任务:如文件读写、网络请求等。

  2. 用户界面响应:确保 GUI 程序在执行后台任务时仍能响应用户操作。

  3. 并发数据处理:处理大规模数据集时,提高数据处理效率。

Python 中的多线程模块

Python 提供了 threading 模块来实现多线程。该模块提供了创建和管理线程的基本功能。

创建线程

使用 threading.Thread 类可以创建一个新线程。以下是一个简单的示例:

import threading

def print_numbers():
    for i in range(10):
        print(i)

# 创建线程
thread = threading.Thread(target=print_numbers)
# 启动线程
thread.start()
# 等待线程完成
thread.join()

使用线程类

除了使用 target 参数指定函数外,还可以通过继承 threading.Thread 类来创建线程:

import threading

class MyThread(threading.Thread):
    def run(self):
        for i in range(10):
            print(i)

# 创建线程实例
thread = MyThread()
# 启动线程
thread.start()
# 等待线程完成
thread.join()

线程同步

由于多个线程共享相同的内存空间,因此需要确保对共享资源的访问是线程安全的。可以使用 threading.Lock 实现线程同步。

import threading

lock = threading.Lock()
counter = 0

def increment_counter():
    global counter
    with lock:
        for _ in range(100000):
            counter += 1

# 创建多个线程
threads = [threading.Thread(target=increment_counter) for _ in range(10)]

# 启动所有线程
for thread in threads:
    thread.start()

# 等待所有线程完成
for thread in threads:
    thread.join()

print(f"Final counter value: {counter}")

线程间通信

可以使用 queue.Queue 实现线程间通信:

import threading
import queue

def producer(q):
    for i in range(5):
        q.put(i)
        print(f"Produced {i}")

def consumer(q):
    while True:
        item = q.get()
        if item is None:
            break
        print(f"Consumed {item}")
        q.task_done()

q = queue.Queue()
thread_producer = threading.Thread(target=producer, args=(q,))
thread_consumer = threading.Thread(target=consumer, args=(q,))

thread_producer.start()
thread_consumer.start()

thread_producer.join()
q.put(None)  # Signal the consumer to exit
thread_consumer.join()

多线程的实际应用

实现并发网络请求

在实际开发中,常常需要发送大量的网络请求。传统的串行处理方法效率较低,通过使用多线程,可以显著提高并发请求的速度。假设需要从多个网站抓取数据,并且希望尽可能快速地完成这项任务。通过多线程,可以同时向多个网站发送请求,而不是一个一个地请求,从而大大减少总的执行时间。

使用 requests 库来发送 HTTP 请求,使用 threading 库来实现多线程。

import threading
import requests

# 待抓取的URL列表
urls = [
    "https://www.example.com",
    "https://www.python.org",
    "https://www.github.com",
    # 更多URL...
]

# 定义线程函数
def fetch_url(url):
    try:
        response = requests.get(url)
        print(f"Fetched {url} with status {response.status_code}")
    except requests.RequestException as e:
        print(f"Error fetching {url}: {e}")

# 创建并启动线程
threads = []
for url in urls:
    thread = threading.Thread(target=fetch_url, args=(url,))
    threads.append(thread)
    thread.start()

# 等待所有线程完成
for thread in threads:
    thread.join()

在上述代码中,定义了一个 fetch_url 函数来发送 HTTP 请求,并在主线程中创建并启动多个子线程,每个线程负责抓取一个 URL。

实现生产者-消费者模式

生产者-消费者模式是一种经典的多线程编程模式,常用于处理需要动态生成和消费数据的场景。通过使用线程安全的队列(如 queue.Queue),我们可以方便地实现这一模式。假设有一个生产者线程,不断生成数据(例如从文件或数据库中读取数据),并将数据放入队列中。同时,有多个消费者线程,从队列中取出数据并进行处理。使用多线程可以让生产和消费过程并行进行,从而提高效率。

以下是一个使用生产者-消费者模式的示例代码:

import threading
import queue
import time

# 创建队列
q = queue.Queue()

# 定义生产者函数
def producer():
    for i in range(10):
        item = f"item_{i}"
        q.put(item)
        print(f"Produced {item}")
        time.sleep(1)  # 模拟生产过程中的延迟

# 定义消费者函数
def consumer():
    while True:
        item = q.get()
        if item is None:
            break
        print(f"Consumed {item}")
        q.task_done()
        time.sleep(2)  # 模拟消费过程中的延迟

# 创建并启动生产者线程
producer_thread = threading.Thread(target=producer)
producer_thread.start()

# 创建并启动多个消费者线程
consumer_threads = []
for _ in range(3):
    thread = threading.Thread(target=consumer)
    consumer_threads.append(thread)
    thread.start()

# 等待生产者线程完成
producer_thread.join()

# 向队列中放入None,通知消费者线程退出
for _ in range(3):
    q.put(None)

# 等待所有消费者线程完成
for thread in consumer_threads:
    thread.join()

print("All tasks are done.")

在这个示例中,创建了一个 queue.Queue 对象作为共享队列,并定义了生产者和消费者函数。生产者函数生成数据并将其放入队列,消费者函数从队列中取出数据进行处理。通过 q.task_done()q.join(),我们可以确保所有任务都被处理完毕。

总结

本文介绍了 Python 中多线程的基本概念、使用场景、创建和管理线程的方法,以及线程同步和线程间通信的实现。通过示例代码,展示了如何在实际应用中使用多线程来提高程序的执行效率和响应速度。

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!


如果想要系统学习Python、Python问题咨询,或者考虑做一些工作以外的副业,都可以扫描二维码添加微信,围观朋友圈一起交流学习。

c4081a8b0ec9d0556127971830dba435.gif

我们还为大家准备了Python资料和副业项目合集,感兴趣的小伙伴快来找我领取一起交流学习哦!

8e00731eca0517f3e2c12eceab251890.jpeg

往期推荐

历时一个月整理的 Python 爬虫学习手册全集PDF(免费开放下载)

Python基础学习常见的100个问题.pdf(附答案)

学习 数据结构与算法,这是我见过最友好的教程!(PDF免费下载)

Python办公自动化完全指南(免费PDF)

Python Web 开发常见的100个问题.PDF

肝了一周,整理了Python 从0到1学习路线(附思维导图和PDF下载)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1860509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

排序算法的优劣,以及优化思路

文章目录 1. 冒泡排序2. 选择排序3. 插入排序4. 快速排序5. 归并排序6. 堆排序应用案例:对一个随机生成的整数列表进行排序基础快速排序快速排序优化:三数取中法 性能测试非递归快速排序实现基础归并排序归并排序的空间优化尝试自底向上归并排序实现堆排…

深圳比创达电子EMC|EMI电磁干扰行业:提升电子产品质量的关键

随着电子技术的飞速发展,电磁干扰(EMI)问题日益凸显,成为影响电子产品性能和市场竞争力的重要因素。 一、EMI电磁干扰行业的概述 电磁干扰,即电子设备在运行过程中产生的电磁波对其他设备或系统产生的干扰。这种干扰…

基于决策树的旋转机械故障诊断(Python)

前置文章: 将一维机械振动信号构造为训练集和测试集(Python) https://mp.weixin.qq.com/s/DTKjBo6_WAQ7bUPZEdB1TA 旋转机械振动信号特征提取(Python) https://mp.weixin.qq.com/s/VwvzTzE-pacxqb9rs8hEVw import…

AI大模型的制造业场景,一文读懂

摘要 AI大模型是通用人工智能发展的重要里程碑。中央会议关于人工智能发展提出三个第一次:第一次提出“通用人工智能”,第一次提出“产业智能化”,第一次提出“把握人工智能等新科技革命浪潮”。 这一轮AI所体现“革命性”特征,不…

防止多次点击,vue的按钮上做简易的防抖节流处理

话不多说,上个视频,看看是不是你要的效果 防抖节流 1.创建一个directive.js // directive.js export default {install(Vue) {// 防重复点击(指令实现)Vue.directive(repeatClick, {inserted(el, binding) {el.addEventListener(click, () > {if (!el.disabled) {el.disabl…

利用LabVIEW和机器学习实现无规律物体识别

针对变化无规律的物体识别,LabVIEW结合机器学习算法提供了一种高效的解决方案。介绍如何使用LabVIEW编程实现此功能,包括所需工具包、算法选择和实现步骤,帮助开发者在无规律的复杂环境中实现高精度的物体识别。 1. 项目概述 无规律物体的识…

YOLOv8模型代码学习

1.参考文献 链接1 2.网络模型解析 2.1卷积神经单元(conv.py) 在该文件中定义了yolov8网络中的卷积神经单元,位置如图所示。 def autopad(k, pNone, d1): # kernel(卷积核), padding(填充), dilation(扩张)"""Pad to same…

PLSQL下ORA-00904:

plsql下查看执行计划报错:ORA-00904:“OTHER_XML”:标识符无效 解决办法: 1.报错的用户登录到sqlplus,执行以下命令: sql> drop table PLAN_TABLE;2.创建表: sql> ?/rdbms/admin/utlxplan.sql; Table created.重新登录plsql按F5选择text: 报错问题解决.

苹果电脑压缩pdf文件,苹果电脑里如何压缩pdf文件

压缩PDF文件是现代办公和日常生活中经常需要处理的一项任务,无论是为了节省存储空间、方便网络传输,还是为了在移动设备上更流畅地阅读文档,学会有效地压缩PDF都显得尤为重要。在本文中,我们将详细探讨压缩PDF的方法,从…

解码数智升级良方:中国一拖、中原传媒、神火股份等企业数字化实践分析

大模型、AI等技术的成熟以及政策法规的细化,数据资源的权属论证、合规确权、资产论证等环节逐渐走向实用性、价值化。 而伴随着“业财税数融”综合性数字化成为企业数字化转型的主流选择,财务部门的纽带属性被放大,财务数据的融合能力成为企业…

【华为HCIA数通网络工程师真题-构建以太网交换网络】

华为HCIA数通网络工程师真题-构建以太网交换网络 一、1-10题 一、1-10题 1、如图所示,四台交换机都运行 STP,各种参数都采用默认值如果交换机C的G0/0/2端口发生阻塞并无法通过该端口发送配置 BPDU,则网络中 blocked 端口多久之后会进入到转发…

【JavaEE精炼宝库】多线程进阶(1)常见锁策略 | CAS | ABA问题

目录 一、常见的锁策略: 1.1 悲观锁 | 乐观锁: 1.2 重量级锁 | 轻量级锁: 1.3 自旋锁 | 挂起等待锁: 1.4 公平锁 | 非公平锁: 1.5 可重入锁 | 不可重入锁: 1.6 互斥锁 | 读写锁: 1.7 面…

Web前端第四次作业

目录 一、编写一个函数,形参是一个数组,返回数组中所有数字的平均值 二、编写一个函数,形参是一个数组,返回数组中的最大值 三、编写一个函数,形参是一个字符串,统计该字符串中每个字母出现的次数&#…

大模型微调方法总结

一 LoRA: 1 低(秩)rank 自适应微调方法 2 背景及本质   大模型的参数更新耗费大量现存为此, 微软的研究者们于2021年通过论文《LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS》提出了低秩适应LoRA 它冻结了预训练的模型权重,并将可…

2005年下半年软件设计师【下午题】试题及答案

文章目录 2005年下半年软件设计师下午题--试题2005年下半年软件设计师下午题--答案 2005年下半年软件设计师下午题–试题 2005年下半年软件设计师下午题–答案

AI绘画Stable Diffusion人物背景替换实操教程,让创意无限延伸

大家好,我是画画的小强 Stable Diffusion以其强大的能力可以实现人物背景的更换。本文将带你深入了解如何利用Stable Diffusion中的Inpaint Anything插件快速且精准地实现人物背景的替换,从而让你的图片焕发新生。 前期准备 本文会使用到Inpaint Anyt…

以敏感数据保护为中心,建立健全高校数据安全治理体系

教育行业数据安全事件频发 2023年8月,南昌某高校3万余条师生个人信息数据在境外互联网上被公开售卖,该校受到责令改正、警告并处80万元人民币罚款的处罚,主要责任人被罚款5万元人民币。2023 年 7月,中国人民大学一名毕业生马某某…

ClickHouse vs. Elasticsearch:十亿行数据的较量

本文字数:15291;估计阅读时间:39 分钟 审校:庄晓东(魏庄) 本文在公众号【ClickHouseInc】首发 Meetup活动 ClickHouse 上海首届 Meetup 讲师招募中,欢迎讲师在文末扫码报名! 引言 这…

2024上海初中生古诗文大会倒计时4个月:单选题真题示例和独家解析

现在距离2024年初中生古诗文大会还有4个多月时间,我们继续来看10道选择题真题和详细解析,以下题目截取自我独家制作的在线真题集,都是来自于历届真题,去重、合并后,每道题都有参考答案和解析。 为帮助孩子自测和练习&…

Chromium下载

https://chromium.woolyss.com/download/ https://www.chromium.org/getting-involved/download-chromium/