深入理解Python中的多进程和多线程

  前言

此篇文章将深入的讲解Python中的多进程和多线程

b1691e6f246947eeb06ee06469621bc2.gif

📝个人主页→数据挖掘博主ZTLJQ的主页

个人推荐python学习系列:

☄️爬虫JS逆向系列专栏 - 爬虫逆向教学

☄️python系列专栏 - 从零开始学python

第一部分:多进程

多进程是指在操作系统中同时运行多个独立的程序或子进程。Python中的multiprocessing模块提供了创建和管理多进程的功能。

案例1:使用多进程进行计算密集型任务

import multiprocessingdef square(n):return n*nif __name__ == '__main__':numbers = [1, 2, 3, 4, 5]pool = multiprocessing.Pool()results = pool.map(square, numbers)pool.close()pool.join()print(results)

解释:

  • 定义了一个square函数,用于计算给定数值的平方。
  • 在主程序中,创建了一个数字列表numbers。
  • 使用multiprocessing.Pool()创建一个进程池pool。
  • 调用pool.map()方法,将square函数应用到numbers列表中的每个数值上进行计算。
  • 最后,输出计算结果。

案例2:使用多进程进行IO密集型任务

import multiprocessing
import requestsdef download(url):response = requests.get(url)content = response.contentwith open('file_' + url.split('/')[-1], 'wb') as file:file.write(content)if __name__ == '__main__':urls = ['http://example.com', 'http://example.org', 'http://example.net']pool = multiprocessing.Pool()pool.map(download, urls)pool.close()pool.join()

解释:

  • 导入requests模块,用于发送HTTP请求。
  • 定义了一个download函数,用于下载给定URL的内容,并保存为文件。
  • 在主程序中,创建了一个URL列表urls。
  • 使用multiprocessing.Pool()创建一个进程池pool。
  • 调用pool.map()方法,将download函数应用到urls列表中的每个URL上进行下载。
  • 最后,所有文件下载完成后,进程池关闭。

案例3:多进程实现并行任务

import multiprocessing
import timedef task(name):print(f'Starting task {name}')time.sleep(2)print(f'Finished task {name}')if __name__ == '__main__':processes = []for i in range(1, 6):p = multiprocessing.Process(target=task, args=(f'Task {i}',))p.start()processes.append(p)for p in processes:p.join()print('All tasks completed.')

解释:

  • 定义了一个task函数,模拟一个耗时的任务,并在开始和结束时打印相关信息。
  • 在主程序中,创建了一个进程列表processes。
  • 使用for循环创建并启动5个子进程,每个子进程执行task函数,并传入不同的任务名称作为参数。
  • 调用join()方法等待所有子进程的执行完成。
  • 最后,打印所有任务完成的提示信息。

第二部分:多线程

多线程是指在一个程序中同时运行多个独立的线程。Python中的threading模块提供了创建和管理多线程的功能。

案例1:使用多线程进行并发请求

import threading
import requestsdef fetch(url):response = requests.get(url)content = response.contentprint(f'Response from {url}: {content}')if __name__ == '__main__':urls = ['http://example.com', 'http://example.org', 'http://example.net']threads = []for url in urls:t = threading.Thread(target=fetch, args=(url,))threads.append(t)t.start()for t in threads:t.join()

解释:

  • 导入requests模块,用于发送HTTP请求。
  • 定义了一个fetch函数,用于请求给定URL的内容,并输出响应内容。
  • 在主程序中,创建了一个URL列表urls。
  • 创建一个线程列表threads来存储所有的子线程。
  • 使用for循环创建子线程,每个子线程都调用fetch函数,并传入不同的URL参数。
  • 调用start()方法启动子线程,使它们开始执行。
  • 最后,使用join()方法等待所有子线程的执行完成,并输出响应结果。

案例2:多线程实现资源共享

import threadingcount = 0
lock = threading.Lock()def increment():global countwith lock:count += 1print(f'Count: {count}')if __name__ == '__main__':threads = []for i in range(10):t = threading.Thread(target=increment)t.start()threads.append(t)for t in threads:t.join()print('Final count:', count)

解释:

  • 定义了一个全局变量count,用于记录递增的值。
  • 创建了一个线程锁lock,用于保护共享资源count的访问。
  • 定义了一个increment函数,使用线程锁来确保每次递增操作的原子性。
  • 在主程序中,创建了一个线程列表threads。
  • 使用for循环创建并启动10个子线程,每个子线程执行increment函数。
  • 调用join()方法等待所有子线程的执行完成。
  • 最后,打印最终的count值。

案例3:多线程队列示例

import threading
import queuedef producer(q, name):for i in range(5):message = f'Message {i} from {name}'q.put(message)print(f'Produced: {message}')def consumer(q, name):while not q.empty():message = q.get()print(f'Consumed by {name}: {message}')if __name__ == '__main__':q = queue.Queue()p1 = threading.Thread(target=producer, args=(q, 'Producer 1'))p2 = threading.Thread(target=producer, args=(q, 'Producer 2'))c1 = threading.Thread(target=consumer, args=(q, 'Consumer 1'))c2 = threading.Thread(target=consumer, args=(q, 'Consumer 2'))p1.start()p2.start()c1.start()c2.start()p1.join()p2.join()c1.join()c2.join()print('All messages consumed.')

多线程队列示例是一个典型的生产者-消费者模型,其中有两个生产者线程(Producer 1和Producer 2)和两个消费者线程(Consumer 1和Consumer 2)。它们共享一个线程安全的队列(Queue)来进行信息交换。

在生产者线程中,每个生产者会循环生成5条消息,并将它们放入队列中。每条消息都包含了消息的编号和产生消息的生产者的名称。生产者线程在生产完所有消息之后结束。

在消费者线程中,每个消费者会不断地从队列中取出消息,并打印出消费的消息以及消费者的名称。消费者线程会一直运行,直到队列为空时才结束。

主线程创建并启动了所有生产者和消费者线程,并等待它们全部执行完毕。最后,主线程打印出"All messages consumed."表示所有消息都被消费完毕。

通过使用线程安全的队列,多线程之间可以安全地进行信息的传递和共享,避免了数据竞争和死锁等多线程编程常见问题。

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

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

相关文章

ssm学生公寓管理系统的设计与实现

ssm学生公寓管理系统的设计与实现106 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归…

mongodb 分片集群部署

文章目录 mongodb 分片部署二进制安装三台config 配置shard 分片安装shard1 安装shard2 安装shard3 安装mongos 安装数据库、集合启用分片创建集群认证文件创建集群用户部署常见问题 mongodb 分片部署 二进制安装 mkdir -p /data/mongodb tar xvf mongodb-linux-x86_64-rhel7…

算法 -汉诺塔,哈夫曼编码

有三个柱子,分别为 from、buffer、to。需要将 from 上的圆盘全部移动到 to 上,并且要保证小圆盘始终在大圆盘上。 这是一个经典的递归问题,分为三步求解: ① 将 n-1 个圆盘从 from -> buffer ② 将 1 个圆盘从 from -> to ③ 将 n-1 个圆盘从 buffer -> to 如果…

opencv android sdk 使用中的问题

Plugin with id ‘kotlin-android’ not found 在build.gradle(:app)中添加以下内容 buildscript {ext {Kotlin_Verion "1.9.10"}dependencies {classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$Kotlin_Verion"}repositories {mavenCentral()} …

论文浅尝 | 利用对抗攻击策略缓解预训练语言模型中的命名实体情感偏差问题...

笔记整理:田家琛,天津大学博士,研究方向为文本分类 链接:https://ojs.aaai.org/index.php/AAAI/article/view/26599 动机 近年来,随着预训练语言模型(PLMs)在情感分类领域的广泛应用&#xff0c…

数据结构--树4.2.2(二叉树--遍历)

目录 一、二叉树的建立 二、二叉树的遍历算法 一、二叉树的建立 CreateBitree(Bitree *t){char c;scanf("%c",&c);if( c){*t NULL;}else{*t(Bitnode*)malloc(sizeof(Bitnode));(*t)->data c;CreateBitree(&(*t)->lchild);CreateBitree(&(*t)-&…

打造个人的NAS云存储-通过Nextcloud搭建私有云盘实现公网远程访问

文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文件共享服…

模拟电子技术基础学习笔记二 杂质半导体

通过扩散工艺,在本征半导体中掺入少量合适的杂质元素,可得到杂质半导体。 按掺入的杂质元素不同,可形成N型半导体和P型半导体 控制掺入杂质元素的浓度,可以控制杂质半导体的导电性能。 一、N型半导体(negative Semic…

ui网页设计实训心得

ui网页设计实训心得篇一 通过这次实训对这门课程的学习,做好网页,并不是一件容易的事,它包括网页的选题、 内容采集整理、 图片的处理、 页面的排版设置、 背景及其整套网页的色调等很多东西。 所以我得出一下总结: 一、 准备资…

CUBLAS库入门教程(从环境配置讲起)

文章目录 前言一、搭建环境二、简单介绍三、 具体例子四、疑问 前言 CUBLAS库是NVIDIA CUDA用于线性代数计算的库。使用CUBLAS库的原因是我不想去直接写核函数。 (当然,你还是得学习核函数该怎么写。但是人家写好的肯定比我自己写的更准确!&…

[PyTorch][chapter 54][Variational Auto-Encoder 实战]

前言: 这里主要实现: Variational Autoencoders (VAEs) 变分自动编码器 其训练效果如下 训练的过程中要注意调节forward 中的kle ,调参。 整个工程两个文件: vae.py main.py 目录: vae main 一 vae 文件名: vae…

typora使用

1.主题配置 先打开主题文件夹, 文件–>>偏好设置–>>外观–>>打开主题文件夹 1.1字体 修改字体需要修改css文件,确定当前所用主题,可以在typora菜单点击主题,看看当前勾选的是哪个主题,比如gith…

iPhone 15 Pro与iPhone 13 Pro:最大的预期升级

如果你在2021年首次发布iPhone 13 Pro时就抢到了它,那么你的合同很可能即将到期。虽然距离iPhone 15系列还有几周的时间,但你可能已经在想:是时候把你的旧iPhone升级为iPhone 15 Pro了吗? 我们认为iPhone 13 Pro是你现在能买到的最好的手机之一。但如果你想在2023年晚些时…

微信小程序 趣味学习与益智游戏系统APP

管理员、用户可通过HBuilder系统手机打开系统,注册登录后可进行管理员后端;首页、个人中心、用户管理、学生分类管理、学一学管理、玩一玩管理、听一听管理、试题管理、练一练管理、系统管理、考试管理,用户前端;首页、学一学、玩…

音视频入门基础理论知识

文章目录 前言一、视频1、视频的概念2、常见的视频格式3、视频帧4、帧率5、色彩空间6、采用 YUV 的优势7、RGB 和 YUV 的换算 二、音频1、音频的概念2、采样率和采样位数①、采样率②、采样位数 3、音频编码4、声道数5、码率6、音频格式 三、编码1、为什么要编码2、视频编码①、…

同一台电脑测.Net和Mono平台浮点运算的差异

float speed 0.1f;float distance 2.0f;long needTime (long)(distance / speed);Log.Debug($"needTime{needTime}"); 结果: .Net平台算出20 Mono平台算出19

【传输层】网络基础 -- UDP协议 | TCP协议

再谈端口号端口号范围划分netstatpidof UDPUDP的特点面向数据报UDP的缓冲区 基于UDP的应用层协议 TCP认识TCP协议的报头理解封装解包理解可靠性TCP工作模式16位窗口大小6位标志位URGACKPSHRSTSYNFIN 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序 在TCP/I…

力扣92. 局部反转链表

92. 反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&am…

计算机网络 | TCP 三次握手四次挥手 |半关闭连接

本来是不愿意写的&#xff0c;可是在实际场景&#xff0c;对具体的描述标志还是模糊不清&#xff0c;基础不扎实&#xff0c;就得承认&#xff01;&#xff01;&#xff01; TCP 连接建立需要解决三大问题&#xff1a; 知道双方存在约定一些参数&#xff0c;如最大滑动窗口值、…

Ubuntu 22.04安装 —— Win11 22H2

目录 Ubuntu使用下载UbuntuVmware 安装图示安装步骤图示 Ubuntu使用 系统环境&#xff1a; Windows 11 22H2Vmware 17 ProUbutun 22.04.3 Server Ubuntu Server documentation | Ubuntu 下载 Ubuntu 官网下载 建议安装长期支持版本 ——> 可以选择桌面版或服务器版(仅包…