Python之进程池、阻塞模式、非阻塞模式、进程间的通信、queue

非阻塞模式

# 当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程
# 但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法.
# 初始化Poo1时,可以指定一个最大进程数,当有新的请求提交到Poo1中时,如果池还没有满,
# 那么就会创建一个新的进程用来执行该请求,但如果池中的进程数已经达到指定的最大值,那么 该请求就会等待
# 直到池中有进程结束,才会创建新的进程来执行。
#阻塞式:添加一个执行一个,然后接着添加下一个
#非阻塞式,全部添加到队列,立刻返回,并不会等待他们执行完毕,但是回调函数是等待任务执行完毕后才调用
import os
import time
from multiprocessing import Pool
from random import random
def task(task_name):
    print("开始做任务",task_name)
    #记录开始时间
    start = time.time()
    #模拟做任务
    time.sleep(random()*2)
    end = time.time()
    return "完成任务用时",(end-start),'进程id',os.getpid()

'''
回调函数,当我们任务做完了,我们想把这个事情通知一下,我们把通知给扔出去了,扔给了回调函数
'''
container = []
def callback_func(n):
    container.append(n)

if __name__ == '__main__':
    #Pool()需要传递参数,整型的参数
    pool = Pool(5)
    tasks = ['听音乐','吃饭','洗衣服','打游戏','散步','看孩子','做饭']
    #模拟循环创建8个任务
    for i in tasks:
        #下面函数表示用的是池子的非阻塞模式,需要传递函数,然后函数需要参数,需要可迭代的参数
        #循环一次池子添加一个任务
        #要使用进程池,要挡住你的主进程,因为进程或者要依靠主进程
        #callback需要传递的参数就是你的回调函数
        #回调函数就是当你的任务完成时,将任务完成的结果返回给回调函数,也就是test1的返回值成了callback_func的参数
        #之后可以在最后产生结果
        pool.apply_async(task,args=(i,),callback=callback_func)
    pool.close() #添加任务结束
    pool.join()#相当于插队,不让你的主进程往下走
    for c in container:
        print(c)

 结果

阻塞模式

#阻塞式
#进程的优点没有体现出来,不可以并行
#添加一个任务执行一个任务,如果一个任务不结束,另外一个让你无就进不来
#进程池:
#pool = Pool(max) 创建进程池对象
# pool.apply()阻塞
# pool.apply_async()非阻塞
# pool.close()
# pool.join()让主进程给子进程让路
import os
import time
from multiprocessing import Pool
from random import random
def task(task_name):
    print("开始做任务",task_name)
    #记录开始时间
    start = time.time()
    #模拟做任务
    time.sleep(random()*2)
    end = time.time()
    print("完成任务用时", (end - start), '进程id', os.getpid())
# container = []
# def callback_func(n):
#     container.append(n)
if __name__ == '__main__':
    pool = Pool(5)
    pool = Pool(5)
    tasks = ['听音乐', '吃饭', '洗衣服', '打游戏', '散步', '看孩子', '做饭']

    for i in tasks:
        pool.apply(task, args=(i,))
    pool.close()
    pool.join()

结果

 

queue

# 当进程平行执行时,数据如何从一个地方传输到另外一个地方,这个时候就需要用到队列了
# 队列就相当于在两个进程中搭个梯子,然后传输数据,queue
from multiprocessing import Queue
# queue需要的参数,通过put往Queue放东西
#规定队列里面的东西不超过5个
#put参数有个timeout,这个参数就是当有个东西等待相应的时间若还是没有空出来,就会报异常
q=Queue(5)
q.put('a')
q.put('b')
q.put('c')
q.put('d')
q.put('e')
print(q.qsize())
if not q.full(): #full用来判断队列是否满了 q.empty()判断队列是不是空的
    q.put('f',timeout=4) #如果你的队列满了,则你现在只能等,除非队列里面空出一个位置
else:
    print("队列已满")

#取出队列的值,同样这个也有个timeout参数,这个就是当你取东西的时间超过了对应时间,就会报异常
#这个异常可以用try去掉
print(q.get())
print(q.get(timeout=2))
print(q.get(timeout=2))
print(q.get(timeout=2))
print(q.get(timeout=2))
print(q.get(timeout=2))
print(q.get(timeout=2))
print(q.get(timeout=2))

结果

 进程间通信

借助queue

# 白大黑
# 开发时间:$[DATE] $[TIME]
from multiprocessing import Process,Queue
from time import sleep


def download(q):
    #模拟图片
    images=['a.jpg','b.jpg','c.jpg']
    #模拟下载图片
    for i in  images:
        print('正在下载',i)
        sleep(0.5)
        q.put(i)

#下载成功后需要把文件送到getfile中,然后getfile拿到这个文件,就把这个文件放到一个具体的位置
#但是现在是两个进程,两个进程是平行的。如何把下载的东西上传到getfile中就是一个问题
#这时queue就出现了
#两者通信当然要保持两者通道是一致的,queue当然使用的是一个
#所以需要两个函数都弄一个参数q,然后使用args参数传进去
def getfile(q):
    while True:
        try:
            file = q.get(timeout=2)
            print('{}文件保存成功'.format(file))
        except:
            print('保存完毕')
            break


if __name__ == '__main__':
    q=Queue(5)
    #当download执行完成后,他就会把剩下的内存回收,这时getfile就不能用了,所以下载的东西可能不完全
    #所以就需要p1这个任务等待一下
    p1 = Process(target=download,args=(q,))
    p2 = Process(target=getfile,args=(q,))
    p1.start()
    #放了join就相当于p1插队了
    p1.join()
    p2.start()

结果

 进程对于全局变量的访问

import os
from multiprocessing import Process
from time import sleep
#当你的子进程调用全局变量的时候,相当于每个子进程会拥有一个自己的m变量,意思是两个子进程的变量m是分开的
#m是不可变类型,可变类型也是同理,这样就实现了多任务
m = 1
def test1(x):
    global m
    while True:
        sleep(x)
        m = m+1
        print("这是任务1",'子',os.getpid(),'父',os.getppid(),m)

def test2(a):
    global m
    while True:
        sleep(a)
        m = m + 1
        #os.getpid进程号os.getppid父进程号
        print('这是任务2','子',os.getpid(),'父',os.getppid(),m)
if __name__ == '__main__':
    #创建进程,这是两个子进程,当你运行程序的时候python解释器就已经默认给你分配了一个进程,然后这个程序里面有创建了两个子进程
    #若是需要传参数,Process有别的属性args这个后面需要跟一个可迭代的,这个里面的就是你给函数传的参数
    #p.run只启动任务不执行进程,p.start启动进程并执行任务.p.terminate终止进程
    p = Process(target=test1,name='任务1',args=(1,))
    p.start()
    print(p.name)
    p1 = Process(target=test2,name="任务2",args=(2,))
    p1.start()
    print(p1.name)

 结果

m是每个进程单独的一个


不嫌弃的点点关注,点点赞 ଘ(੭ˊᵕˋ)੭* ੈ✩‧₊˚

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分享5款专注于实用简洁的工具软件

​ 有时候一些小工具,能给你带来一些意想不到的效果,我们来看看下面这5款工具,你又用过其中几款呢? 1. 高效操作利器——Quicker ​ Quicker是一款旨在提高操作效率的强大工具。通过简单的自定义设置,用户能够创建个…

幼儿教育管理系统|基于jsp 技术+ Mysql+Java的幼儿教育管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可…

C++中的Union: 内存与类型转换技巧

在C中,union是一种特殊的数据类型,允许在相同的内存位置存储不同类型的数据。union提供了一种高效地利用内存的方式,但同时也要求开发者更加小心地处理数据以避免类型错误。 1. 基本定义 union定义了一个可以存储多种类型但任意时刻只能存储…

未来国家的希望在实体经济 民众的希望在投资理财

2024年经济的车轮已经滚滚而来,在阳春三月这个希望无限的季节,香港贵金属交易商、香港金银贸易场AA类147号行员金田金业认为,我们国家的希望在于实体经济发展,而民众要实现个人财务自由,仅仅靠打工还不够,更…

C++ Qt开发:QUdpSocket实现组播通信

Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QUdpSocket组件实现基于UDP的组播通信…

PyTorch二次反向传播报错

First StagenetF, netC = backbone_net(args, return_type=001xy)base_network = nn.Sequential(netF, netC)optimizer_f = optim.Adam(netF

leetcode(Hot100)——数组篇

1、两数之和 本题使用哈希法&#xff0c;用一个哈希Map保存数组的值以及对应下标&#xff0c;代码如下&#xff1a; class Solution {public int[] twoSum(int[] nums, int target) {HashMap<Integer,Integer> map new HashMap<>();for(int i0; i<nums.length…

没有经验就开通抖店,你会遇到以下这些问题!2024抖店教程(新版)

我是王路飞。 没有经验的人去做抖店的话&#xff0c;都会遇到哪些问题呢&#xff1f; 大概率逃脱不开这些问题&#xff1a; 店铺的类型怎么选&#xff1f; 店铺的流量从哪来&#xff1f; 没有货源但又担心做无货源模式会被平台判定违规&#xff1b; 怎么才能快速把店铺做…

利用Google成功开发客户的15个方法!

做外贸的小伙伴们都知道Google是搜索开发客户比较重要的平台&#xff0c;基本上所有的客户都能在Google上找到蛛丝马迹。 今天小编给大家分享15个有关Google客户开发的方法&#xff0c;大家赶快Get起来! 01.产品名称importers importers可以用importer代替。不同的产品或者行…

数据库简介与MySQL编译安装

1数据库基础 什么是数据库 数据库&#xff08;Database&#xff09;是一个有组织的数据存储系统&#xff0c;用于有效地存储、检索、管理和维护数据。数据库系统允许用户以结构化的方式存储和操作大量数据&#xff0c;并提供了一种可靠的方法来管理和维护这些数据&#xff0c…

内网渗透学习-环境搭建

1、环境搭建测试 虚拟机网络环境配置&#xff0c;模拟外网和内网 主机操作系统网络内网ip外网ip物理主机window10vmnet8192.168.70.1攻击机kali Linuxvmnet8192.168.70.134域控主机win server 2008 r2vmnet0192.168.52.138域成员主机win server 2k3vmnet0192.168.52.141服务器…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《含光储充的配网虚拟电厂二次调频随机模型预测控制策略 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

51单片机-蜂鸣器

1.蜂鸣器的介绍 无源蜂鸣器不能一直通电&#xff0c;无源蜂鸣器内部的线圈较小&#xff0c;易烧坏 蜂鸣器的驱动 达林顿晶体管&#xff08;npn型&#xff09; 应用&#xff1a; 按下独立按键同时蜂鸣器响起提示音&#xff0c;数码管显示对应的独立按键键码 #include <REG…

windows服务器iis更换彻底删除 原443 ssl证书以及一个服务器运行多个独立域名网站并绑定多个证书的方法

服务器上的433 ssl证书,可以让网站以https加密方式访问,但是这个证书会占用443端口,iis7版本,只能安装一个443证书,所以.原来的过期了.需要删除.删除方式,不是进运行 winr的mmc 而是进iis的默认的总的主页面板(不是点击具体的网站或者程序池),点击服务器证书.进去才能删除.否则…

程序员下班以后做什么副业合适?

我就是一个最普通的网络安全工程师&#xff0c;出道快10年了&#xff0c;不出意外地遭遇到瓶颈期&#xff0c;但是凭技术在各大平台挖漏洞副业&#xff0c;硬是妥妥扛过来了。 因为对于程序员来讲&#xff0c;这是个试错成本很低、事半功倍的选择。编程技能是一种强大生产力&a…

OpenGL-高斯模糊原理

OpenGL-高斯模糊原理 正态分布 上图人类的智商分布比例&#xff0c;大多数人的智商集中在85-115&#xff0c;超高和超低智商的人只占很小的比例&#xff0c;柱状图可用一条曲线拟合&#xff0c;如图中红色曲线所示. 这个钟形曲线就是正态分布曲线. 正态分布曲线体现了宇宙中很…

【C++】static关键字及其修饰的静态成员变量/函数详解

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Visual Studio 2022 目录 什么是static? static的引入 静态数据的存储 全局(静态)存储区 static成员概念 static成员特性 ststic成员的应用 利用static实现一个可以计算程序中正在使用的类对象有…

使用 Docker Compose 安装 Harbor

Harbor 是一个企业级开源仓库&#xff0c;用于存储和管理 Docker 镜像。它提供了一系列功能&#xff0c;包括镜像复制、安全扫描和漏洞管理。Harbor 可以通过多种方式安装&#xff0c;其中之一是使用 Docker Compose。 先决条件 在安装 Harbor 之前&#xff0c;您需要满足以下…

golang sync.Map之如何设计一个并发安全的读写分离结构?

在 golang中&#xff0c;想要并发安全的操作map&#xff0c;可以使用sync.Map结构&#xff0c;sync.Map 是一个适合读多写少的数据结构&#xff0c;今天我们来看看它的设计思想&#xff0c;来看看为什么说它适合读多写少的场景。 如下&#xff0c;是golang 中sync.Map的数据结构…

详细分析Js中的Promise.all基本知识(附Demo)

目录 1. 基本知识2. Demo3. 实战 1. 基本知识 Promise.all 是 JavaScript 中的一个方法&#xff0c;它接受一个由 Promise 对象组成的数组作为参数&#xff0c;并在所有 Promise 对象都变为 resolved&#xff08;已完成&#xff09;状态时才返回一个新的 Promise 对象&#xf…