在这里插入图片描述

文章目录

    • 多线程基础概念
    • 多进程基础概念
    • 多线程的优劣势
    • 多进程的优劣势
    • 实战应用:网络爬虫
    • 实战应用:图像处理

Python作为一门功能强大的编程语言,提供了多种并发模型,使得我们能够在同一时间执行多个任务,从而提高程序的执行效率。

在众多并发模型中,多线程和多进程是最常用的两种。它们各自有着不同的优劣势,并适用于不同的场景。

多线程是一种轻量级的并发模型,适用于I/O密集型任务,如文件读写、网络请求等。

在多线程中,所有线程共享同一进程的内存空间,这使得线程之间的通信和数据共享变得非常高效,由于Python的全局解释锁(GIL),多线程在处理CPU密集型任务时并不能充分利用多核CPU的优势。

相对而言,多进程是更为独立的并发模型,每个进程拥有独立的内存空间,因此非常适合CPU密集型任务,如复杂计算、图像处理等。

由于每个进程运行在独立的Python解释器中,多进程可以绕过GIL限制,充分利用多核CPU的性能。不过,由于进程之间的通信需要通过进程间通信(IPC)机制实现,因此数据共享的效率不如多线程。

多线程基础概念

多线程是一种并发执行模型,允许一个程序在不同的线程中同时运行多个操作。这种模型的一个显著特点是,所有线程共享同一进程的内存空间。

这种共享内存的特性使得线程之间的数据交换变得非常方便,因为它们可以直接访问和操作共享的数据,而无需像多进程那样通过复杂的进程间通信(IPC)机制。

多线程示例

import threadingdef print_numbers():for i in range(5):print(f"Number: {i}")thread = threading.Thread(target=print_numbers)
thread.start()
thread.join()

在这段代码中,我们创建了一个新的线程来执行print_numbers函数。线程启动后,它会输出数字0到4。

当调用thread.join()时,主线程会等待该线程执行完成后再继续运行。这种机制确保了多线程程序的顺序性和可控性。

然而,线程共享内存也带来了线程安全问题。

在多线程环境中,多个线程可能会同时访问和修改共享数据,这可能导致数据不一致或竞争条件。

为了避免这些问题,我们需要使用线程同步机制,如锁(Lock)、条件变量(Condition)、信号量(Semaphore)等,来确保线程间的数据访问是安全的。

例如,可以使用锁来保护共享数据的访问:

import threadinglock = threading.Lock()def thread_safe_function():with lock:# 访问和修改共享数据pass

通过合理使用这些同步机制,我们可以确保多线程程序的正确性和稳定性。

多线程非常适合I/O密集型任务,如网络请求、文件读写等,在这些场景下,它可以显著提升程序的响应速度和效率。

多进程基础概念

多进程是一种并发模型,它为每个进程分配独立的内存空间。

这意味着进程之间的数据交换需要通过进程间通信(IPC)机制来实现,如管道(Pipe)、队列(Queue)和共享内存等。

多进程适用于CPU密集型任务,因为每个进程可以独立运行在不同的CPU核心上,从而充分利用多核CPU的计算能力。

多进程示例:

from multiprocessing import Processdef print_numbers():for i in range(5):print(f"Number: {i}")process = Process(target=print_numbers)
process.start()
process.join()

这段代码与多线程示例类似,但我们使用的是multiprocessing模块。

每个进程独立运行,互不干扰,这使得多进程模型在处理CPU密集型任务时具有很大优势,因为它可以绕过Python的全局解释锁(GIL),实现真正的并行执行。

由于每个进程都有独立的内存空间,多进程模型天然地避免了线程安全问题,不需要担心多个进程同时访问和修改同一块内存。

这种独立性也带来了更多的内存开销,因为每个进程都需要维护自己的内存空间。

在需要进行进程间通信时,可以使用multiprocessing模块提供的IPC机制。例如,使用队列来交换数据:

from multiprocessing import Process, Queuedef worker(q):q.put('Data from process')queue = Queue()
process = Process(target=worker, args=(queue,))
process.start()
print(queue.get())
process.join()

通过合理选择多进程模型,我们可以在处理需要大量计算的任务时显著提高程序的性能。

虽然多进程会引入额外的内存和进程管理开销,但在合适的场景下,它的优势是显而易见的。

多进程是一种强大且灵活的并发模型,能够帮助我们在开发高性能应用程序时充分利用现代硬件的多核能力。

多线程的优劣势

优点

  • 线程之间通信简单,数据共享方便。
  • 适合I/O密集型任务,如网络请求、文件读写。

缺点

  • 由于Python的GIL(全局解释器锁),多线程在CPU密集型任务中并不能提升性能。
  • 需要注意线程安全问题,可能需要使用锁等机制。

多进程的优劣势

优点

  • 各个进程独立运行,适合CPU密集型任务。
  • 不受GIL限制,可以充分利用多核CPU。

缺点

  • 进程间通信复杂,数据共享不如线程方便。
  • 进程启动和切换的开销较大。

实战应用:网络爬虫

在编写网络爬虫时,使用多线程可以显著加速I/O操作,尤其是在处理多个网页请求时,多线程允许我们同时发起多个网络请求,从而提高爬虫的效率和数据抓取速度。

多线程爬虫示例:

import threading
import requestsurls = ['http://example.com', 'http://example.org']def fetch_url(url):response = requests.get(url)print(f"{url}: {response.status_code}")threads = [threading.Thread(target=fetch_url, args=(url,)) for url in urls]
for thread in threads:thread.start()
for thread in threads:thread.join()

每个线程独立工作,互不干扰,这种并发请求的方式可以大大提升爬虫的效率,因为网络I/O操作通常比CPU操作耗时,而多线程正好可以利用这个特点,在等待网络响应的同时处理其他请求。

使用多线程抓取网页时,我们需要谨慎处理。要注意遵守网站的robots.txt文件中的规则,确保爬虫行为在网站允许的范围内。

应该设置合理的请求频率,以避免给目标服务器带来过大的负担,导致服务器过载甚至被封禁IP。

可以通过引入请求延迟或使用线程池来控制请求的频率和并发数量。

还需注意处理网络请求中的异常情况,如超时、重定向和错误响应等,以确保爬虫的健壮性和稳定性。

通过合理运用多线程技术,我们可以开发出高效、可靠的网络爬虫,快速获取所需的数据,同时也不忘遵循网络爬虫的道德和法律规范。

实战应用:图像处理

在进行大量图像处理任务时,使用多进程可以有效地利用CPU资源,提升处理效率。

多进程允许我们在多个CPU核心上同时执行任务,这对于图像处理这种CPU密集型操作尤为适用。

使用多进程进行图像滤镜处理的示例:

from multiprocessing import Pool
from PIL import Image, ImageFilterdef process_image(image_path):with Image.open(image_path) as img:img = img.filter(ImageFilter.BLUR)img.save(f"processed_{image_path}")image_paths = ['image1.jpg', 'image2.jpg']
with Pool(processes=2) as pool:pool.map(process_image, image_paths)

在这个例子中,我们使用multiprocessing.Pool来管理多个进程,每个进程独立处理一张图片的滤镜操作。

通过将任务分配给多个进程,我们能够同时处理多张图片,从而充分利用多核CPU的并行计算能力。

这种并行处理方式可以显著缩短图像处理的时间,特别是在需要处理大量图片或应用复杂滤镜时。

Pool对象提供了一种简便的方法来并行化任务,我们可以指定进程数来控制并行度。

在此例中,设置了两个进程来处理两张图片。pool.map()方法将任务分发给进程池中的每个进程,确保每个图像处理任务独立运行,互不干扰。

使用多进程进行图像处理时,还需注意内存占用和进程间通信开销。

虽然多进程能够绕过Python的全局解释锁(GIL),实现真正的并行计算,但每个进程都有独立的内存空间,这可能会增加内存消耗,在处理大批量图像时,合理配置进程数和内存资源显得尤为重要。

通过合理运用多进程技术,我们可以大幅提高图像处理任务的执行效率,快速完成对大量图片的处理,同时也能确保处理结果的准确性和一致性。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解

Spring Boot 整合 Nacos 教程(3000字) 一、Nacos 简介 Nacos 是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台,致力于帮助开发者更轻松地构建云原生应用。它支持多种注册中心协议(如 Dubbo、Spring Cloud、Kubernete…

VMware 虚拟机装 Linux Centos 7.9 保姆级教程(附资源包)

安装 VMware 17.5.1 centos 7.9 ​ 1、下载资源包(虚拟机镜像) VMware-17.5.1 安装包秘钥.zipLinux Centos 7.9 镜像 2、centos 7.9 下载地址 1、Centos 官网 2、阿里巴巴镜像站 3、查看网络命令 ifconfig 或 ip addr 4、登陆服务器 ssh stark192.168.3…

STM32超声波模块

一:超声波模块1:工作原理采用IO触发测距,给至少10us的高电平信号。 模块自动发送8个40KHz的方波,自动检测是否有信号返回。 有信号返回,通过IO输出一高电平,高电平持续时间就是超声波从发射到返回的时间声波…

RK3568项目(十一)--linux驱动开发之mipi屏幕调试

目录 一、引言 二、MIPI DSI 屏幕 ------>2.1、MIPI联盟 ------------>2.1.1、多媒体部分 ------------>2.1.2、硬件协议 ------------>2.1.3、D-PHY功能模式及速率 ------------>2.1.4、分辨率计算 ------>2.2、MIPI-DSI硬件连接 ------>2.3、传…

C语言小游戏——飞机大战

目录 引言 开发环境与工具准备 1. 开发环境配置 2. 资源文件准备 游戏设计与架构 1. 游戏核心数据结构 2. 游戏全局变量 游戏核心功能实现 1. 游戏初始化 2. 游戏主循环 3. 游戏渲染 4. 游戏状态更新 关键游戏机制实现 1. 敌机生成系统 2. 碰撞检测系统 3. 敌机…

SQLite的可视化界面软件的安装

1、如下图所示,DB Browser软件,在压缩包中。2、首先解压到一个文件夹中。例如(D:\\DB Browser)文件夹。解压后的内容如下图。3、将解压后的DB Browser文件夹,剪切到D:\Program Files\目录中。如下两图。win10操作系统下…

基于 STM32H743VIT6 的边缘 AI 实践:猫咪叫声分类 CNN 网络部署实战(已验证)中一些bug总结

前言前面发了一篇文章基于 STM32H743VIT6 的边缘 AI 实践:猫咪叫声分类 CNN 网络部署实战(已验证)。这里面有一些我遇到过的bug,当时基本都花了很长的时间才解决。这里将这些bug总结一下方便后续查阅。1.使用cubemx插件解析AI模型…

【机器学习】突破分类瓶颈:用逻辑回归与Softmax回归解锁多分类世界

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

Android gradle plugin agp8.6.1发布时间

Android gradle plugin agp8.6.1发布时间 Android Gradle Plugin (AGP) 的版本 8.6.1 是在2023年发布的。具体来说,它是在2023年4月发布的。这个版本的更新包括了多个重要的改进和修复,旨在提升开发者在Android开发过程中的体验和效率。 主要更新包括&am…

闭包的两种设计模式

闭包设计模式 概述 闭包是 JavaScript 中的一个重要概念,它允许内层函数访问外层函数的变量。在实际开发中,闭包经常被用于实现特定的设计模式,主要包括辅助函数模式和工厂模式。 1. 辅助函数模式(Helper Function Pattern&#x…

力扣119:杨辉三角Ⅱ

力扣119:杨辉三角Ⅱ题目思路代码题目 给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。 思路 杨辉三角的规律: 第n行有n1个数,n从0开始每行的第一个数和最后一个数都是1。除了第一行的数其他的数都是由它左上角和右上角的…

@Linux自建证书 Nginx+HTTPS

文章目录Linux自建证书并配置Nginx HTTPS1. 准备工作2. 安装必要的工具3. 自建证书脚本3.1 创建CA根证书(可选,用于自签名证书链)3.2 创建服务器证书脚本4. 证书文件说明5. 配置Nginx使用HTTPS5.1 创建证书存放目录5.2 配置Nginx站点5.3 启用…

解决 RAGFlow报错 `peewee.OperationalError: (1045)`:MySQL 容器密码错误排查手记

文章目录 🕵️‍♂️ 深度排查过程 🔧 完美解决方案:同步真实密码 ✅ 验证结果 📌 经验总结与最佳实践 问题现象: 部署 ragflow 时遭遇以下错误,且访问前端页面无响应: peewee.OperationalError: (1045, "Access denied for user root@192.168.48.6")关键线…

lwIP WebSocket 客户端 TCP PCB 泄漏问题分析与解决

在嵌入式开发中,使用 lwIP 实现 WebSocket 客户端时,偶尔会遇到反复连接导致 TCP PCB(Protocol Control Block)泄漏,最终连接数达到上限(如 4)后无法再建立新连接的问题。本文将结合实际案例&am…

k8s之Attach 和 Mount

Attach 和 Mount 一、核心概念对比操作Attach(挂载设备)Mount(挂载文件系统)定义将存储卷(如 EBS、NFS 等)连接到宿主机将已 Attach 的存储设备映射为宿主机上的文件系统路径执行者云提供商驱动&#xff08…

API Gateway HTTP API 控制客户端访问 IP 源

前言 在 API Gateway REST API 中我们可以配置 Resource policy 来实现对特定客户端 IP 地址的限制. 然而 HTTP API 并不提供这个功能, 不过我们可以用 Lambda 搓一个 Authorizer 实现等效的功能. 创建 Lambda authorizer import json import os import ipaddressdef lambda…

Linux搭建LAMP环境(CentOS 7 与 Ubuntu 双系统教程)

Linux搭建LAMP环境 一、LAMP 环境核心概念 定义:由 Linux、Apache、MySQL、PHP 四大组件组成的开源 Web 应用平台本质:四个独立开源软件的组合体,因长期协同使用形成高度兼容性,成为动态网站和服务器的主流解决方案 二、LAMP 四大…

c# 开机自动启动程序

以下是两种实现C#软件开机自启动的常用方法&#xff0c;根据需求选择适合的方案&#xff1a; 方法1&#xff1a;通过注册表实现&#xff08;需管理员权限&#xff09; using Microsoft.Win32; using System.Diagnostics;public static class AutoStartManager {/// <summa…

C语言---动态内存管理

为什么要有动态内存分配我们在学习动态内存管理之前&#xff0c;一直都是通过开辟变量&#xff0c;或者是开辟数组的方式来在内存的栈区开辟空间的&#xff0c;但是这样的开辟方式有局限性&#xff0c;因为一旦开辟之后&#xff0c;它们的大小就无法改变&#xff0c;就缺少了很…

C++标准库(std)详解

C标准库&#xff08;std&#xff09;详解——目录C标准库&#xff08;std&#xff09;详解一、命名空间&#xff08;namespace&#xff09;二、主要组件1. 输入输出流&#xff08;<iostream>&#xff09;2. 字符串处理&#xff08;<string>&#xff09;3. STL容器&…