零基础学python之高级编程(6)---Python中进程的Queue 和进程锁,以及进程池的创建 (包含详细注释代码)

Python中进程的Queue 和进程锁,以及进程池的创建

文章目录

  • Python中进程的Queue 和进程锁,以及进程池的创建
  • 前言
  • 一、进程间同步通信(Queue)
  • 二、进程锁(Lock)
  • 三、创建进程池Poor
      • pool 类方法:
  • End!


前言

大家好,上一篇文章,我们初步接触了进程的概念及其应该如何创建一个进程等等,今天我们继续来深入学习一下进程中的进程间同步 Queue进程锁lock 还有进行创建一个进程池pool 等等,我们开始今天的学习吧 !


一、进程间同步通信(Queue)

我们在使用进程的时候,有时候我们需要进行进程之间的通信,multiprocessing 模块提供了Queue类 来实现不同进程之间的通信.

Queue():括号内传的参数表示最大可接受的消息数量;没有传参或者数量为负数,则表示最大可接受的数量没有上限(直到内存的尽头)

Queue.put(item, block, timeout) : 将item消息写入队列中,block默认为True.

  • 如果block使用默认值,且没有设置timeout秒数,消息队列如果已经没有空间可以写入,将会被阻塞,直到从消息队列腾出空间为止
  • 如果block使用默认值,设置了timeout秒数,则会等待timeout秒,若还没有空间,则会抛出异常’queue.full’.

我们首先先创建一个进程对象:

在这里插入图片描述
上图就是我们queue 中的方法,接下来我们看看如何使用queue.

from  multiprocessing import Queueq = Queue(3)  # 创建一个Queue 对象,设置最大可接受put对象为3个
q.put('消息1')
q.put('消息2')
print(q.full()) # 判断队列是否满了 这里面输出False
q.put('消息3')
print(q.full()) #判断队列是否满了 这里面输出Trueprint(q.get()) # 获取队列中的消息,获取后把消息从队列中删除if not q.full(): # 判断队列是否满,如果不满就继续将消息写入队列q.put('消息4')print(q.get())
print(q.get())
print(q.get())

运行结果:

在这里插入图片描述

from  multiprocessing import Queueq = Queue(3)  # 创建一个Queue 对象,设置最大可接受put对象为3个
q.put('消息1')
q.put('消息2')
print(q.full()) # 判断队列是否满了 这里面输出False
q.put('消息3')
print(q.full()) #判断队列是否满了 这里面输出Trueprint(q.get())
if not q.full():q.put('消息4')# print(q.get())
# print(q.get())
# print(q.get())if not q.empty():  # 判断队列是否为空for i in range(q.qsize()): print(q.get_nowait())

运行结果:
在这里插入图片描述

注意:

Queue.put_nowait(item)===>Queue.put(item, False)

Queue.get_nowait()===>Queue.get(False)

Queue.get(block, timeout):获取队列中的一条信息,然后将其从队列中移除,block默认为True

  • 如果block使用默认值,且没有设置timeout秒数,消息队列如果为空,将会被阻塞,直到从消息队列读到消息为止.

  • 如果block使用默认值,设置了timeout秒数,则会等待timeout秒,若还没有消息,则会抛出异常’queue.empty’.

如果block值为False,消息队列如果为空,则立即抛出异常’queue.empty

接下来我们进行一次完整的进程间的通信

import multiprocessing  #导包
import time
import randomdef write(q):  # 定义一个函数for i in ['a', 'b', 'c']:  print('放入:', i)q.put(i) # 分别将a,b,c 消息传入队列time.sleep(random.random())def read(q):while True:if not q.empty():print('获取:', q.get()) 获取队列中的消息time.sleep(random.random())else:breakif __name__ == '__main__':q = multiprocessing.Queue()  # 创建一个Queue对象 qpw = multiprocessing.Process(target=write, args=(q, ))  # 创建一个子进程 pw ,并将queue 对象传入pr = multiprocessing.Process(target=read, args=(q, ))   # 创建一个子进程 pr,并将queue对象传入pw.start() # pw 子进程开始pw.join()  # 等待 pw进程结束 pr.start() # pr 子进程开始pr.join() # 等待 pr进程结束print('结束')

运行结果:

在这里插入图片描述

二、进程锁(Lock)

Python进程锁是用来在多进程程序中对共享资源进行同步访问的一种机制。
当多个进程需要同时访问某个共享资源时,可能会出现竞争条件(race condition),导致数据不一致或错误的结果。进程锁可以用来保证在任意时刻只有一个进程能够访问共享资源,从而避免竞争条件的发生。

进程锁的主要作用是确保在某个进程正在使用共享资源时,其他进程无法访问该资源,直到当前进程释放锁为止。这样可以保证共享资源在任意时刻只会被一个进程修改,从而避免数据不一致或错误的结果。

Python中的进程锁可以通过使用multiprocessing模块中的Lock类来实现。通过调用lock.acquire()方法可以获得锁,其他进程如果尝试获得同一个锁则会被阻塞。而通过调用lock.release()方法可以释放锁,允许其他进程获得锁并访问共享资源。

需要注意的是,进程锁只能在同一个计算机的多个进程之间起作用,无法在不同计算机之间的进程之间起作用。如果需要进行跨网络的进程同步,可以考虑使用分布式锁的机制。

Python中可以使用多种方式实现进程锁,以下是常用的两种:

使用multiprocessing.Lock():multiprocessing.Lock()是Python标准库中的一个进程锁实现。可以通过acquire()方法获得锁,并在任务完成后使用release()方法释放锁。
例如:

from multiprocessing import Lock, Processdef func(lock, num):lock.acquire()try:# 临界区代码print(f"进程{num}获得了锁")finally:lock.release()print(f"进程{num}释放了锁")if __name__ == "__main__":lock = Lock()processes = []for i in range(5):p = Process(target=func, args=(lock, i))processes.append(p)p.start()for p in processes:p.join()

也可使用multiprocessing.Manager().Lock():multiprocessing.Manager()是一个多进程共享数据的管理器。可以通过Manager().Lock()方法创建一个进程锁。具体使用方式与multiprocessing.Lock()相同,只是创建锁的方式有所不同。
例如:

from multiprocessing import Process, Managerdef func(lock, num):lock.acquire()try:# 临界区代码print(f"进程{num}获得了锁")finally:lock.release()print(f"进程{num}释放了锁")if __name__ == "__main__":manager = Manager()lock = manager.Lock()processes = []for i in range(5):p = Process(target=func, args=(lock, i))processes.append(p)p.start()for p in processes:p.join()

三、创建进程池Poor

Python进程池:是一种用于管理和复用多个进程的工具。进程池可以提高程序的并发处理能力,通过复用已经创建的进程,避免频繁创建和销毁进程的开销。

pool 类方法:

Pool()括号内表示处理的进程数量

apply_async(func, args, kwargs):使用非阻塞方式调用func(并行执行,阻塞就是必须等待上一个进程退出才能执行下一个进程)

close():关闭进程池,不在接收新的进程

terminate():不管任务是否完成,立即终止

join():阻塞,等待所有子进程结束,必须在close之后使用.

import multiprocessing
import timedef run(f):time.sleep(1)return f * fif __name__ == '__main__':test = [1, 2, 3, 4, 5, 6]# print('顺序:')# s = time.time()  # 计算当前时间# for i in test:#     print(run(i))e = time.time()# print('顺序执行时间:', int(e-s))# map(函数名, 可迭代对象):循环将可迭代对象传递给函数执行print('并发:')pool = multiprocessing.Pool(5)  # 创建能够有5条进程的进程池r1 = pool.map(run, test)pool.close()pool.join()e2 = time.time()print('并发时间:', int(e2 - e))print(r1)

运行结果:
在这里插入图片描述

在进程池里进行进程间的通信
例如:

import multiprocessing, os, time, randomdef write(q):print('write(%s)启动' % os.getpid())for i in ['a', 'b', 'c', 'd', 'e']:q.put(i)def read(q):print('read(%s)启动' % os.getpid())for i in range(q.qsize()):print('获取:', q.get())if __name__ == '__main__':print('主进程(%s)开始' % os.getpid())q = multiprocessing.Manager().Queue()pool = multiprocessing.Pool()pool.apply_async(write, (q, ))pool.apply_async(read, (q, ))pool.close()pool.join()print('主进程结束')

运行结果:

在这里插入图片描述


End!

讲的不好,多多见谅,我们下次再见!

更多优质文章点这里

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

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

相关文章

【tingsboard开源平台】环境准备和安装

文章目录 环境准备:1.安装JAVA2.安装maven环境3.安装nodeJS(16.15.1)4.安装git环境5.安装npm依赖关系6.放入文件fetched7.安装IDEA 环境准备: 1.安装JAVA 以安装java11为例,安装tingsboard需要的jdk 下载地址:https://www.oracle.com/java/technologi…

初识C++(二)引用,内联函数,auto

目录 1.引用的概念与用法: 1.1引用特性: 1.2使用场景 1.2.1做参数 1.3传值、传引用效率比较 1.4引用做返回值 1.5引用和指针的对比 2.内联函数 3.auto关键字 4. 基于范围的for循环(C11) 5.指针空值nullptr(C11) 1.引用的概念与用法:…

腾讯云4核8G服务器支持多少人同时在线?

腾讯云4核8G服务器价格:轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线?支持30个并发数,可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…

独立看门狗

什么是独立看门狗?它有什么用?什么时候用?不用行不行? 独立看门狗(Independent Watchdog,简称IWDG)是一种微控制器中常见的硬件保护机制。它的主要作用是监视系统的运行状态,当系统出…

2024 年 15 个最佳自动化 UI 测试工具【建议收藏】

Web 开发行业正在不断发展,许多最佳自动化 UI 测试工具可用于测试基于 Web 的项目,以确保它没有错误并且每个用户都可以轻松访问。这些工具可帮助您测试您的 Web 项目并使其完全兼容用户端的要求和需求。 UI 自动化测试工具可测试基于 Web 的应用程序或软…

JRT菜单

上一章搭建了登录界面的雏形和抽取了登录接口。给多组使用登录和菜单功能提供预留,做到不强行入侵别人业务。任何产品只需要按自己表实现登录接口后配置到容器即可共用登录界面和菜单部分。最后自己的用户关联到JRT角色表即可。 登录效果 这次构建菜单体系 首先用…

Transformer的前世今生 day09(Transformer的框架概述)

前情提要 编码器-解码器结构 如果将一个模型分为两块:编码器和解码器那么编码器-解码器结构为:编码器负责处理输入,解码器负责生成输出流程:我们先将输入送入编码器层,得到一个中间状态state,并送入解码器…

号码采集协议讲解

仅供学习研究交流使用 需要的进去拿源码或者成品

上位机图像处理和嵌入式模块部署(qmacvisual图像拼接)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 qmacvisual本身提供了图像拼接的功能。功能本身比较有意思的。大家如果拍过毕业照,特别是那种几百人、上千人的合照,应该就…

Rust编程(二)语法和数据类型

编程规范 类C语法,函数需要定义,指令需要以;结尾。需要大括号{} 文件名,变量,函数命名使用snake case,eg:new_function() 结构体,特征命名,使用大驼峰命名,e…

微信小程序商城构建全栈应用

今天,将之前大学朋友分享给我的好几个小程序内容,简单的从百度网盘下载了一下,重新回顾小程序内容,重新构建融合一些不同语言的元素。下面是网盘的简单截图。 我先挑选了一个微信小程序商城项目,简单看了看&#xff0…

中霖教育:不是会计专业能参加24年的中级会计师考试吗?

经常有很多同学问:我不是会计专业的能报中级会计师考试吗? 先来看报名需要满足的必要条件: 1、大学专科学历,从事会计工作满5年。 2、大学本科学历或学士学位,从事会计工作满4年。 3、第二学士学位或研究生班毕业&#xff0c…

Rust编程(三)生命周期与异常处理

生命周期 生命周期,简而言之就是引用的有效作用域。在大多数时候,我们无需手动的声明生命周期,因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据: {let r;{let x …

Partisia Blockchain:真正做到兼顾隐私、高性能和可拓展的公链

目前,包括 Secret Network、Oasis Protocol 等在内的绝大多数以隐私为特性的可编程公链,在兼顾隐私的同时,在可拓展以及性能上或多或少的有所牺牲,即难以对诸多实际应用场景进行支撑。这归咎于链的设计以及共识机制的不合理&#…

袁志佳:前端全栈工程师精英班

教程介绍 本套课程涵盖大前端的全部领域,并对传统的Web前端全栈深入教学。如利用前端知识开发 AI、VR、AR、iOS、Android、PC、Server、智能硬件。 同时我们将核心打造 JavaScript语言新发展、Vue源码分析、前端持续集成方案汇总、MV*框架深度分析 、前端图形学、N…

Python爬虫如何快速入门

写了几篇网络爬虫的博文后,有网友留言问Python爬虫如何入门?今天就来了解一下什么是爬虫,如何快速的上手Python爬虫。 一、什么是网络爬虫 网络爬虫,英文名称为Web Crawler或Spider,是一种通过程序在互联网上自动获取…

目前2024年腾讯云4核8G服务器租用优惠价格表

2024年腾讯云4核8G服务器租用优惠价格:轻量应用服务器4核8G12M带宽646元15个月,CVM云服务器S5实例优惠价格1437.24元买一年送3个月,腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图: 腾讯云4核8G服务器优惠价格 轻…

虚拟机如何在原有磁盘上扩容

虚拟机未开启状态–菜单栏–虚拟机–快照–拍摄快照–拍摄快照– 菜单栏–虚拟机–快照–快照管理器–点击刚刚的快照1–删除–是– 文件–新建或者打开–硬盘(以本人Win 10.64.3GL为例)–虚拟机设置–硬件– 硬盘(SATA)–磁盘实…

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中,可能开发某个功能不需要了,或者想要回退到之前历史的某个commit, 放弃后来修改的内容。 放弃已修改的内容 如果未提交,直接使用 …

二分算法的变种----查找递增可重复数组边界

public class test {//数组长度a,b,c为8,d为7;static int[] a {3,5,8,8,8,9,9,10};static int[] b {8,8,8,8,8,8,8,8};static int[] c {0,0,0,0,0,0,0,0};static int[] d {0,0,0,0,0,0,0};public static void main(String[] args) {int target 0;System.out.pr…