第十章 多线程、多进程和线程池编程

目录

11.1 多线程编程

什么是多线程?

创建和启动线程

线程同步

11.2 多进程编程

什么是多进程?

创建和启动进程

进程间通信

11.3 线程池和进程池

什么是线程池和进程池?

使用线程池

使用进程池

11.4 选择多线程还是多进程

适用场景

性能比较

11.5 实战案例:并发下载文件

多线程下载文件

多进程下载文件

11.6 使用线程池和进程池下载文件

线程池下载文件

进程池下载文件

11.7 处理异常和超时

处理异常

设置超时

11.8 共享状态和锁

11.9 线程局部存储

11.10 本章小结


在现代计算中,高效的并发和并行处理是提升程序性能的关键。Python提供了多种机制来实现并发和并行处理,包括多线程、多进程和线程池编程。本章将深入探讨这些概念及其在Python中的实现,帮助您更好地掌握这些技术,编写高效、可扩展的代码。

11.1 多线程编程

什么是多线程?

多线程是一种并发编程技术,它允许程序同时执行多个线程。线程是轻量级的进程,它们共享相同的内存空间,可以在多个处理器核心上并行执行。多线程适用于I/O密集型任务,例如文件操作和网络通信。

创建和启动线程

在Python中,可以使用threading模块创建和管理线程。

示例代码:

import threadingdef print_numbers():for i in range(10):print(i)# 创建线程
thread = threading.Thread(target=print_numbers)# 启动线程
thread.start()# 等待线程结束
thread.join()
线程同步

多线程编程中,多个线程可能会访问共享资源,因此需要同步机制来避免竞态条件。Python提供了多种同步原语,例如锁(Lock)、条件变量(Condition)和信号量(Semaphore)。

示例代码:

import threadinglock = threading.Lock()
counter = 0def increment_counter():global counterfor _ in range(1000):with lock:counter += 1threads = [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}")

11.2 多进程编程

什么是多进程?

多进程是一种并行编程技术,它允许程序同时执行多个进程。进程是独立的执行单元,每个进程都有自己的内存空间。多进程适用于CPU密集型任务,例如科学计算和数据处理。

创建和启动进程

在Python中,可以使用multiprocessing模块创建和管理进程。

示例代码:

import multiprocessingdef print_numbers():for i in range(10):print(i)# 创建进程
process = multiprocessing.Process(target=print_numbers)# 启动进程
process.start()# 等待进程结束
process.join()
进程间通信

由于进程之间不共享内存,需要通过进程间通信(IPC)机制来交换数据。常见的IPC机制包括管道(Pipe)和队列(Queue)。

示例代码:

import multiprocessingdef producer(queue):for i in range(10):queue.put(i)print(f"Produced {i}")def consumer(queue):while not queue.empty():item = queue.get()print(f"Consumed {item}")queue = multiprocessing.Queue()producer_process = multiprocessing.Process(target=producer, args=(queue,))
consumer_process = multiprocessing.Process(target=consumer, args=(queue,))producer_process.start()
consumer_process.start()producer_process.join()
consumer_process.join()

11.3 线程池和进程池

什么是线程池和进程池?

线程池和进程池是管理和复用多个线程或进程的技术。通过使用池,可以减少创建和销毁线程或进程的开销,提高资源利用率。Python提供了concurrent.futures模块来方便地创建和管理线程池和进程池。

使用线程池

线程池通过管理多个线程来执行任务,适用于I/O密集型任务。

示例代码:

from concurrent.futures import ThreadPoolExecutordef print_numbers(n):for i in range(n):print(i)with ThreadPoolExecutor(max_workers=3) as executor:futures = [executor.submit(print_numbers, 10) for _ in range(3)]for future in futures:future.result()
使用进程池

进程池通过管理多个进程来执行任务,适用于CPU密集型任务。

示例代码:

from concurrent.futures import ProcessPoolExecutordef compute_square(n):return n * nwith ProcessPoolExecutor(max_workers=3) as executor:futures = [executor.submit(compute_square, i) for i in range(10)]results = [future.result() for future in futures]
print(results)

11.4 选择多线程还是多进程

适用场景
  • 多线程:适用于I/O密集型任务,例如文件读写、网络通信等。由于Python的GIL(全局解释器锁)限制,多线程在CPU密集型任务中效率不高。
  • 多进程:适用于CPU密集型任务,例如科学计算、数据处理等。多进程可以利用多核CPU的优势,绕过GIL限制。
性能比较

在选择多线程和多进程时,需要权衡任务的性质、系统资源和实现复杂性。

示例代码:性能比较

import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutordef compute_square(n):return n * nnumbers = range(10**6)start = time.time()
with ThreadPoolExecutor(max_workers=4) as executor:executor.map(compute_square, numbers)
print(f"Thread pool time: {time.time() - start:.2f} seconds")start = time.time()
with ProcessPoolExecutor(max_workers=4) as executor:executor.map(compute_square, numbers)
print(f"Process pool time: {time.time() - start:.2f} seconds")

11.5 实战案例:并发下载文件

通过一个实际案例,展示如何使用多线程和多进程实现并发下载文件。

多线程下载文件

示例代码:

import threading
import requestsdef download_file(url):response = requests.get(url)filename = url.split("/")[-1]with open(filename, 'wb') as file:file.write(response.content)print(f"Downloaded {filename}")urls = ["http://example.com/file1","http://example.com/file2","http://example.com/file3",
]threads = [threading.Thread(target=download_file, args=(url,)) for url in urls]for thread in threads:thread.start()for thread in threads:thread.join()
多进程下载文件

示例代码:

import multiprocessing
import requestsdef download_file(url):response = requests.get(url)filename = url.split("/")[-1]with open(filename, 'wb') as file:file.write(response.content)print(f"Downloaded {filename}")urls = ["http://example.com/file1","http://example.com/file2","http://example.com/file3",
]processes = [multiprocessing.Process(target=download_file, args=(url,)) for url in urls]for process in processes:process.start()for process in processes:process.join()

11.6 使用线程池和进程池下载文件

线程池下载文件

示例代码:

from concurrent.futures import ThreadPoolExecutor
import requestsdef download_file(url):response = requests.get(url)filename = url.split("/")[-1]with open(filename, 'wb') as file:file.write(response.content)print(f"Downloaded {filename}")urls = ["http://example.com/file1","http://example.com/file2","http://example.com/file3",
]with ThreadPoolExecutor(max_workers=3) as executor:executor.map(download_file, urls)
进程池下载文件

示例代码:

from concurrent.futures import ProcessPoolExecutor
import requestsdef download_file(url):response = requests.get(url)filename = url.split("/")[-1]with open(filename, 'wb') as file:file.write(response.content)print(f"Downloaded {filename}")urls = ["http://example.com/file1","http://example.com/file2","http://example.com/file3",
]with ProcessPoolExecutor(max_workers=3) as executor:executor.map(download_file, urls)

11.7 处理异常和超时

在并发和并行编程中,处理异常和设置超时是确保程序健壮性的重要手段。

处理异常

示例代码:

from concurrent.futures import ThreadPoolExecutor, as_completeddef risky_task(n):if n == 5:raise ValueError("Something went wrong!")return n * nwith ThreadPoolExecutor(max_workers=3) as executor:futures = [executor.submit(risky_task, i) for i in range(10)]for future in as_completed(futures):try:result = future.result()print(f"Result: {result}")except Exception as e:print(f"Exception: {e}")
设置超时

示例代码:

from concurrent.futures import ThreadPoolExecutor, TimeoutErrordef slow_task(n):import timetime.sleep(n)return nwith ThreadPoolExecutor(max_workers=3) as executor:future = executor.submit(slow_task, 5)try:result = future.result(timeout=2)print(f"Result: {result}")except TimeoutError:print("Task timed out")

11.8 共享状态和锁

在多线程编程中,共享状态需要同步,以避免竞态条件。可以使用锁(Lock)来保护共享资源。

示例代码:

import threadinglock = threading.Lock()
shared_counter = 0def increment_counter():global shared_counterfor _ in range(1000):with lock:shared_counter += 1threads = [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: {shared_counter}")

11.9 线程局部存储

线程局部存储(Thread-Local Storage, TLS)用于在多线程环境中为每个线程提供独立的存储空间。

示例代码:

import threadingthread_local = threading.local()def process_data():thread_local.data = threading.current_thread().nameprint(f"Processing data for {thread_local.data}")threads = [threading.Thread(target=process_data) for _ in range(5)]for thread in threads:thread.start()for thread in threads:thread.join()

11.10 本章小结

在本章中,我们深入探讨了Python中的多线程、多进程和线程池编程。我们介绍了多线程和多进程的基本概念、创建和管理方法,以及它们的适用场景和性能比较。我们还讨论了线程池和进程池的使用,展示了如何通过实际案例实现并发下载文件。最后,我们探讨了处理异常和超时、共享状态和锁以及线程局部存储等高级主题。

多线程和多进程编程是编写高效并发和并行程序的基础,掌握这些技术可以显著提高程序的性能和可扩展性。希望这篇博客能够帮助您深入理解和应用Python的多线程、多进程和线程池编程。

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

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

相关文章

vue3 vxe-grid修改currentPage,查询数据的时候,从第一页开始查询

1、当我们设置好VxeGrid.Options进行数据查询的时候,下面是可能的设置&#xff1a; const gridOptions reactive<BasicTableProps>({id: UserTable,showHeaderOverflow: false,showOverflow: true,keepSource: true,columns: userColumns,size: small,pagerConfig: {cur…

【常见开源库的二次开发】基于openssl的加密与解密——单向散列函数(四)

目录&#xff1a; 目录&#xff1a; 一、什么是单项散列函数&#xff1f; 1.1 如何验证文件是否被修改过 1.2 单项散列函数&#xff1a; 二、单向hash抗碰撞 2.1 弱抗碰撞&#xff08;Weak Collision Resistance&#xff09; 2.2 强抗碰撞&#xff08;Strong Collision Resista…

[GXYCTF2019]Ping Ping Ping1

打开靶机 结合题目名称&#xff0c;考虑是命令注入&#xff0c;试试ls 结果应该就在flag.php。尝试构造命令注入载荷。 cat flag.php 可以看到过滤了空格,用 $IFS$1替换空格 还过滤了flag&#xff0c;我们用字符拼接的方式看能否绕过,ag;cat$IFS$1fla$a.php。注意这里用分号间隔…

【光伏发电功率预测】方法综述学习笔记2《光伏发电功率超短期预测方法综述》

本文参考《光伏发电功率超短期预测方法综述》&#xff1a;https://d.wanfangdata.com.cn/periodical/ChlQZXJpb2RpY2FsQ0hJTmV3UzIwMjQwNzA0Eg5nZHlqczIwMjMwNzAyNBoIeHp4NW40YmU%3D 文章目录 摘要&#xff1a;引言1. 光伏发电功率的影响因素分析1.1传递过程中的影响因素1.1.1…

DDei在线设计器-数据格式说明

数据格式说明 DDei的所有设计数据都以文件为单位保存在一个JSON对象中。JSON对象包含了全量的页签、舞台、图层、控件的位置以及属性信息。开发人员可以存储这个JSON到服务端数据库中&#xff0c;从而轻易的实现保存功能&#xff1b;也解析这个JSON&#xff0c;将其转换成自己业…

对红酒品质进行数据分析(python)

http://t.csdnimg.cn/UWg2S 数据来源于这篇博客&#xff0c;直接下载好csv文件。 这篇内容均在VScode的jupyter notebook上完成&#xff0c;操作可以看我的另一篇博客&#xff1a;http://t.csdnimg.cn/69sDJ 一、准备工作 1. 导入数据库 #功能是可以内嵌绘图&#xff0c;并…

用了6年git,不知道cherry-pick是啥意思

背景 可能是测试开发角色原因&#xff0c;平时很少有代码冲突或多人协同的编码场景。今天有个协同项目&#xff0c;需要提交自己的代码到其它业务的代码库中&#xff0c;这个代码库是分支开发分支上线模式&#xff0c;同时会有多个同事提交代码&#xff0c;然后模块负责的同学…

常用优秀内网穿透工具(实测详细版)

文章目录 1、前言2、安装Nginx3、配置Nginx4、启动Nginx服务4.1、配置登录页面 5、内网穿透5.1、cpolar5.1.1、cpolar软件安装5.1.2、cpolar穿透 5.2、Ngrok5.2.1、Ngrok安装5.2.2、随机域名5.2.3、固定域名5.2.4、前后端服务端口 5.3、NatApp5.4、Frp5.4.1、下载Frp5.4.2、暴露…

【数学建模】——【线性规划】及其在资源优化中的应用

目录 线性规划问题的两类主要应用&#xff1a; 线性规划的数学模型的三要素&#xff1a; 线性规划的一般步骤&#xff1a; 例1&#xff1a; 人数选择 例2 &#xff1a;任务分配问题 例3: 饮食问题 线性规划模型 线性规划的模型一般可表示为 线性规划的模型标准型&…

vue2.0结合使用 el-scrollbar 和 v-for实现一个横向滚动的元素列表,并且能够自动滚动到指定元素(开箱即用)

效果图&#xff1a; 代码&#xff1a; <div class"gas-mode-item-body"><el-scrollbar style"width: 300px;height: 100%;" wrap-style"overflow-y:hidden" ref"scrollbarRef"><div style"display: flex&quo…

Python Linux环境(Centos8)安装minicoda3+jupyterlab

文章目录 安装miniconda安装python环境启动 最近服务器检查&#xff0c;我下面的服务器有漏洞&#xff0c;不得已重装了&#xff0c;正好记录下怎么从零到python写代码。 安装miniconda miniconda是anconda的精简版&#xff0c;就是管理python环境的得力助手。 # 创建一个名…

7.18 学习笔记 解决分页越界问题 及分页查询

1.解决分页越界 1.1出现的问题 于是我索性把分页去掉想是不是就可以了&#xff0c;结果发现还不行 1.2解决方法 就当我找了一两个小时抓耳挠腮时&#xff0c;万幸在csdn上找到了相关的帖子&#xff0c;在此感谢一下那位大佬。 原因是我的实体类中没有构造方法&#xff0c;那…

软考系规百天备考攻略:基础阶段的三轮强化

早在今年4-5月份的时候&#xff0c;我就曾经讲过系统规划与管理师的备考建议&#xff0c;也就是先从教程学起&#xff0c;先读教程&#xff0c;而且我也说过&#xff0c;不要迷信任何培训班或者培训视频&#xff0c;任何培训班或者培训视频都不能取代你认真读至少一遍教程&…

BIOMOD2 物种分布模拟教程

原文链接&#xff1a;BIOMOD2 物种分布模拟教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247609373&idx5&sn492e7597314a5f9e358c35e4780b275f&chksmfa826dfacdf5e4ecf8ac06bdeba5469b31650bdbefbc8fb88b79c0f332714c453a4cc058d29f&token155…

Calibration相机内参数标定

1.环境依赖 本算法采用张正友相机标定法进行实现&#xff0c;内部对其进行了封装。 环境依赖为 ubuntu20.04 opencv4.2.0 yaml-cpp yaml-cpp安装方式&#xff1a; &#xff08;1&#xff09;git clone https://github.com/jbeder/yaml-cpp.git #将yaml-cpp下载至本地 &a…

15- 微分方程

对三角函数不敏感

模块化沙箱:解锁数据防泄密的终极密码

在这个数字化时代&#xff0c;数据已经成为企业最宝贵的资产之一。然而&#xff0c;数据泄露的威胁如同暗夜中的幽灵&#xff0c;随时可能侵袭企业的信息安全防线。面对日益复杂的内外部风险&#xff0c;企业亟需一种既高效又灵活的安全解决方案&#xff0c;来保护其核心数据不…

专业PDF编辑工具:Acrobat Pro DC 2024.002.20933绿色版,提升你的工作效率!

软件介绍 Adobe Acrobat Pro DC 2024绿色便携版是一款功能强大的PDF编辑和转换软件&#xff0c;由Adobe公司推出。它是Acrobat XI系列的后续产品&#xff0c;提供了全新的用户界面和增强功能。用户可以借助这款软件将纸质文件转换为可编辑的电子文件&#xff0c;便于传输、签署…

透视矫正插值

https://www.cnblogs.com/straywriter/articles/15889273.html https://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf https://8.136.115.103/perspective-correct-interpolation%E9%80%8F%E8%A7%86%E6%A0%A1%E6%AD%A3%E6%8F%92%E5%80%BC/ 透视矫正…

Postfix+Dovecot+Roundcube开源邮件系统搭建系列4:Dovecot安装配置

1. Dovecot安装 安装Dovecot&#xff1a; yum -y install dovecot dovecot-mysql 启动服务并设置开机自启动&#xff1a; systemctl start dovecot systemctl enable dovecot 2. Dovecot配置 Dovecot配置文件目录&#xff1a;/etc/dovecot&#xff0c;在该目录中dovecot.…