多进程面试题汇总


在这里插入图片描述

这里写目录标题

  • 一、多进程
    • 1、进程的定义:
    • 2、单核多任务CPU执行原理
    • 3、进程的优点和缺点
    • 4、创建进程1
    • 5、创建进程2
    • 6、进程池
      • 6.1、进程池的作用
      • 6.2、原理图
      • 6.3、使用进程池的优点
    • 7、进程间的通信(Queue)
      • 7.1、需求1:采用多进程将100加到110
      • 7.2、需求2
    • 8、进程间的通信(Pipe)
      • 8.1、Queue和Pipe的区别:
  • 二、计算(CPU)密集型和IO密集型

一、多进程

1、进程的定义:

顾名思义,就是进行中的程序。进程是python中最小的资源分配单元,进程之间的数据,资源是不共享的、是隔离的;每启动一个进程,都要独立分配资源和拷贝访问的数据;进程是重量级别的,在进程中,需要处理的问题包括进程间通信,临界区管理和进程调度,所以进程的启动和销毁的代价是比较大的。

  • 1、windows任务管理器中的每个任务都是一个进程
  • 2、进程可以直接占用CPU、内存、磁盘、网络、GPU
  • 3、打开一个浏览器就是,就是启动了一个浏览器进程;打开一个记事本,就是启动了一个记事本进程。
    在这里插入图片描述

2、单核多任务CPU执行原理

在这里插入图片描述
10年前:单核多任务cpu运行:
整个cpu分割成多个cpu时间片段,每个时间片段执行一个任务,当执行任务1时,任务2和任务3处于等待状态,因为时间片段很短毫秒级别的,所以当把时间拉长为1s时,这些任务都执行了,给人的感官是并行执行的。

3、进程的优点和缺点

优点:
1、可以使用计算机多核,进行任务的并发执行,提高执行效率,运行不受其他进程影响,创建方便
2、空间独立,数据安全
缺点:
1、进程的创建和删除消耗的系统资源较多
2、全局变量在多个进程中不能共享
3、在子进程中修改全局变量对父进程中的全局变量没有影响。因为父进程在创建子进程时对全局变量做了一个备份,父进程中的全局变量与子进程的全局变量完全是不同的两个变量。全局变量在多个进程中不能共享。

4、创建进程1

创建进程用到Process类。
p = Process(target=sub_process_run, args=('子进程1',), name="子进程1")。

  • target:运行的函数。
  • args:传入到子进程中的参数。
  • name:子进程名字。
  • 主进程:读取01创建进程.py文件,边解释边运行;当运行到第17行的时候,创建一个子进程,在已有的主进程的之上又创建了一个子进程。
  • 子进程的名字为子进程1。
  • 如果启动了子进程(p.start()),那么就调用target函数,如果函数有参数,那么就通过args中的参数进行传递。
  • p.start():启动子进程。
  • p.join():让主进程一直等待,直到p这个子进程结束。
import os
import time
from multiprocessing import Processdef sub_process_run(name):time.sleep(5)print(f'子进程的名字:{name}')print(f'子进程ID是:{os.getpid()}')if __name__ == '__main__':print(f'主进程ID是:{os.getpid()}')# 创建进程,target:运行的函数# args:传入到子进程中的参数# name:子进程名字p = Process(target=sub_process_run, args=('子进程1',), name="子进程1")# 主进程:读取01创建进程py文件,边解释边运行;当运行到第17行的时候,创建一个子进程,在已有的主进程的之上又创建了一个子进程# 子进程的名字为子进程1# 如果启动了子进程(p.join()),那么就调用target函数,如果函数有参数,那么就通过args中的参数进行传递# 启动子进程p.start()p.join()  # 让主进程一直等待,p这个子进程结束print('主进程结束')

在这里插入图片描述

5、创建进程2

自定义一个进程类,需要继承Process类。
进程启动之后自动调用的函数;只有run()这块代码才是子进程执行的代码。
代码中3个进程是同时执行任务的——》多进程并行执行。
p = MyProcess(name=f"进程{i}")

  • p.start():启动子进程。
  • p.join():主进程等待3个子进程全部执行结束后,开始执行主进程。
    • join():是一个阻塞函数
    • 为什么要用列表? 10个子进程可以并行执行
  • 多线程是并发。
  • 多进程是并行。
import os
import time
from multiprocessing import Processclass MyProcess(Process):"""这是定义一个自己的进程类"""def __init__(self,name):super().__init__()self.name=namedef run(self):"""进程启动之后自动调用的函数只有这块代码才是子进程执行的代码"""time.sleep(5)print(f'子进程的名字:{self.name}')print(f'子进程ID是:{os.getpid()}')print(f'子进程ID{os.getpid()}结束')if __name__ == '__main__':print(f'主进程ID是:{os.getpid()}')process_list=[]# todo 3个进程是同时执行任务的——》多进程并行执行for i in range(3):# 创建子进程p = MyProcess(name=f"进程{i}")# 启动子进程p.start()process_list.append(p)for p in process_list:p.join()  # 主进程等待3个子进程全部执行结束后,开始执行主进程print('主进程结束')'''
多线程是并发
多进程是并行
'''

在这里插入图片描述

6、进程池

大家思考一个问题:在一台计算机中进程可以无限制的创建吗?

6.1、进程池的作用

进程池的作用:当进程数过多,用于限制进程数。pool可以提供和指定数量的进程,供用户调用。当有新的请求提交到pool中时。如果池还没有满,那么就会创建一个新的进程来执行该请求;但如果池中的进程数已经达到规定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程。

6.2、原理图

绿色:子进程没有工作,处于空闲状态(子进程没有调用任务函数)
粉色:子进程处于工作状态(子进程调用了任务函数)
在这里插入图片描述
在这里插入图片描述

6.3、使用进程池的优点

1.提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间
2.节省内存空间

进程池使用Pool类
pl = Pool(5):创建进程池,最多支持5个进程同时执行

  • Pool(5):创建多个进程,表示可以同时执行的进程数量为5个。默认大小是CPU的核心数果。
    join():进程池对象调用join,会等待进程池中所有的子进程结束完毕再去结束父进程。
    close():如果我们用的是进程池,在调用join()之前必须要先调用close(),并且在close()之后不能再继续往进程池请求

pl.apply_async(func=sub_process_run, args=(f'进程{i}',))
pl.close():进程池关闭

import os
import time
from multiprocessing import Process, Pooldef sub_process_run(name):"""进程启动之后自动调用的函数只有这块代码才是子进程执行的代码"""print(f'子进程的名字:{name}')print(f'子进程ID是:{os.getpid()}')print(f'子进程ID{os.getpid()}结束')time.sleep(5)if __name__ == '__main__':print(f'主进程ID是:{os.getpid()}')pl = Pool(5)  # 创建进程池,最多支持5个进程同时执行for i in range(10): #现在有10个请求进到进程池中pl.apply_async(func=sub_process_run, args=(f'进程{i}',))pl.close()  # 进程池关闭pl.join()print('主进程结束')

注意:
因为我们Pool(4)指定了同时最多只能执行4个进程(Pool进程池默认大小是CPu的核心数),但是我们多放入了6个进程进入我们的进程池,所以程序一开始就会只开启4个进程。
而且子进程执行是没有顺序的,先执行哪个子进程操作系统说了算的。而且进程的创建和销毁也是非常消耗资源的,所以如果进行一些本来就不需要多少耗时的任务你会发现多进程甚至比单进程还要慢。

7、进程间的通信(Queue)

大家思考一下:在多进程中可以使用global+全局变量来共享数据吗?

现在设想你需要两个进程,
一个进程(接收进程)产生数据(比如从网站上爬虫,或者从websocket接收数据等),
另一个进程(转发进程)对产生的数据进行处理并转发(比如计算并处理之后上传数据库,或者发送给websocket等)。这是一个非常常见的应用场景,
直接硬写global+变量是不行的。

使用Queue类实现进程之间的通信
初始化Q对象:q=Queue()
将数据加入到队列中:q.put(100)
从队列中拿出数据:a = q.get()

进程间数据通信之Queue示意图:
在这里插入图片描述
mq.put(i) 子进程1发送数据到队列Queue中,子进程2和子进程3从队列中获取数据
Queue可以称为通信的中间件

7.1、需求1:采用多进程将100加到110

import os
import time
from multiprocessing import Process, Pool,Queue'''
进程池中不能用Queue
'''def sub_process_run(name,q):"""进程启动之后自动调用的函数只有这块代码才是子进程执行的代码"""print(f'子进程的名字:{name}')print(f'子进程ID是:{os.getpid()}')print(f'子进程ID{os.getpid()}结束')time.sleep(5)#从队列中拿出数据a = q.get()a += 1q.put(a)print(f'子进程{os.getpid()}结束,a的值为{a}')if __name__ == '__main__':q=Queue()#将数据加入到队列中q.put(100)print(f'主进程ID是:{os.getpid()}')pl=[]# todo 3个进程是同时执行任务的——》多进程并行执行for i in range(10):# 创建子进程p = Process(target=sub_process_run,args=(f'进程{i}',q))# 启动子进程p.start()pl.append(p)for p in pl:p.join()  # 主进程等待3个子进程全部执行结束后,开始执行主进程print('主进程结束')"""
阻塞函数有哪些?join、recv
"""

在这里插入图片描述

7.2、需求2

我们有两个进程,一个进程负责写(write)一个进程负责读(read)。当写的进程写完某部分以后要把数据交给读的进程进行使用,这时候我们就需要使用到了multiprocessing模块的Queue (队列):write(将写完的数据交给队列,再由队列交给read()
在这里插入图片描述
在这里插入图片描述
mq.put(i) writer进程负责把数据写入Queue
mq.get(True) 负责从Queue中读取数据,get函数是一个阻塞的函数,当队列中没有数据时,会一直阻塞在这里。
pr.terminate() 强制杀死pr进程

8、进程间的通信(Pipe)

Pipe直译过来的意思是"管"或"管道",该种实现多进程编程的方式,和实际生活中的管〈管道)是非常类似的。通常情况下,管道有2个口,而Pipe 也常用来实现2个进程之间的通信,这2个进程分别位于管道的两端,—端用来发送数据,另一端用来接收数据。
1、导入:from multiprocessing import Pipe
2、进程间数据通信之Pipe示意图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1、p1,p2=Pipe():Pipe创建之后得到管道的两端,必须这样写,不能写成(p1=Pipe(),p2=Pipe())
2、self.pipe.send(i) :write进程负责把数据通过管道发送给另一个进程
3、value=self.pipe.recv():当管道中没有数据,该行代码一直阻塞
4、recv函数是阻塞函数

8.1、Queue和Pipe的区别:

Queue:实现多个进程之间通信的
Pipe:实现1对1,单个进程之间的通信

二、计算(CPU)密集型和IO密集型

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、浮点运算、对视频进行高清解码(每一帧是一张图片,一秒钟有25帧,也就是说视频的每秒有25张图片,一张图片又有很多的像素)等等,全靠CPU的运算能力。

  • 计算密集型应该充分使用CPU资源,那就需要使用多进程

这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

第二种任务的类型是IO(Input、Output)密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。


在这里插入图片描述

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

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

相关文章

GPIO八种工作模式

目录 一、推挽输出 二、开漏输出 三、复用推挽输出 四、复用开漏输出 五、浮空输入 六、上拉输入 七、下拉输入 八、模拟输入 GPIO八种配置模式,原理和使用场景,硬件原理如下图: 一、推挽输出 1、 原理 当控制栅极为低电平时&#x…

C++ STL: list使用及源码剖析

list使用 list常用函数及使用&#xff08;1&#xff09; #include <iostream> #include <list> #include <algorithm>int main() {// 创建liststd::list<int> myList {5, 2, 9, 1, 5, 6};// 打印liststd::cout << "Original list: &quo…

VS Code添加环境变量

有时候你会发现即使添加了环境变量, 打开VS Code的命令行终端也找不到对应的环境变量。遇到这种情况可以通过给VS Code的终端独立添加对应环境变量解决: 步骤1. 找到设置 步骤2. 找到windows终端环境变量配置 3. 在此处配置然后重新打开一个终端即可 (完)

ZISUOJ 2022年算法基础公选课练习四(Map)

说明&#xff1a; 博主为了提早预习数据结构和C的一些知识&#xff0c;自己琢磨外加查阅资料所写的代码&#xff0c;题目来源于22年初的学院老师组织的算法基础公选课的练习。我的代码甚至思路肯定存在许多不足和错误&#xff0c;欢迎大家批评指正。 题目列表&#xff1a; 问题…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核基础-互斥锁mux

目录 一、互斥锁基本概念二、互斥锁运行机制三、互斥锁开发流程四、互斥锁使用说明五、互斥锁接口六、代码分析&#xff08;待续...&#xff09; 一、互斥锁基本概念 互斥锁又称互斥型信号量&#xff0c;是一种特殊的二值性信号量&#xff0c;用于实现对共享资源的独占式处理。…

STM32——OLED菜单(二级菜单)

文章目录 一.补充二. 二级菜单代码 简介&#xff1a;首先在我的51 I2C里面有OLED详细讲解&#xff0c;本期代码从51OLED基础上移植过来的&#xff0c;可以先看完那篇文章&#xff0c;在看这个&#xff0c;然后按键我是用的定时器扫描不会堵塞程序,可以翻开我的文章有单独的定时…

Flutter Android开发 梳理Google Material Design颜色体系

前言 做安卓开发&#xff08;Kotlin语言&#xff09;&#xff0c;Flutter开发的人员应该都听说过谷歌一直推崇的Material Design&#xff0c;而Material Design Color是其推崇的颜色体系&#xff0c;具体来说&#xff0c;Material Design Color是一套旨在帮助设计师和开发者创…

Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现

0x01 产品简介 Panalog是一款日志审计系统,方便用户统一集中监控、管理在网的海量设备。 0x02 漏洞概述 Panalog日志审计系统 libres_syn_delete.php接口处存在远程命令执行漏洞,攻击者可执行任意命令,接管服务器权限。 0x03 影响范围 version <= MARS r10p1Free 0…

java+springboot+vue试题库在线学习系统05umj

技术路线&#xff1a; B/S架构&#xff0c;后端springboot框架&#xff0c;前端Vue.js框架。 主要功能模块&#xff08;至少六大功能&#xff09;&#xff0c;参考任务书并拓展 &#xff08;1&#xff09;用户管理模块&#xff1a;规定不同角色的用户对系统中各个功能模块的使用…

【经验】JLINK无法(单步)调试,JLINK固件的烧写

昨天终于准备开始进行S3C6410的裸机开发&#xff0c;写好了程序&#xff0c;编译生成了.axf文件&#xff0c;一切顺利的准备利用JLINK进行在线调试了&#xff0c;突然有种成功就在前面的感觉&#xff0c;Jlink也能被电脑正常的识别&#xff0c;利用AXD进行Jlink的相关设置也很正…

安卓自定义画板

包含功能&#xff1a; 包含 获取当前画板的截图、设置画笔样式、获取画笔样式、设置画笔宽度、获取画笔宽度、设置画笔颜色、获取画笔颜色、加载图片、获取图片位图对象、设置图片位图对象&#xff0c;并在画布上绘制图片、撤销上一步操作、重做上一步撤销的操作、清空所有绘图…

Dirty PageTable

前言 Dirty PageTable 是一种针对堆相关漏洞的利用手法&#xff0c;主要就是针对 PTE 进行攻击。 参考文章&#xff1a; Dirty Pagetable: A Novel Exploitation Technique To Rule Linux Kernel – 该利用方式提出原文 上述文章已经讲的非常清楚了&#xff0c;就是实操写 e…

挑战杯 python区块链实现 - proof of work工作量证明共识算法

文章目录 0 前言1 区块链基础1.1 比特币内部结构1.2 实现的区块链数据结构1.3 注意点1.4 区块链的核心-工作量证明算法1.4.1 拜占庭将军问题1.4.2 解决办法1.4.3 代码实现 2 快速实现一个区块链2.1 什么是区块链2.2 一个完整的快包含什么2.3 什么是挖矿2.4 工作量证明算法&…

CentOS7.9+Kubernetes1.29.2+Docker25.0.3高可用集群二进制部署

CentOS7.9Kubernetes1.29.2Docker25.0.3高可用集群二进制部署 Kubernetes高可用集群&#xff08;Kubernetes1.29.2Docker25.0.3&#xff09;二进制部署二进制软件部署flannel v0.22.3网络&#xff0c;使用的etcd是版本3&#xff0c;与之前使用版本2不同。查看官方文档进行了解…

红队打靶练习:HACK ME PLEASE: 1

信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.61.128 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.61.2 00:50:56:f0:df:20 …

大学建筑专业的搜题软件?大学搜题工具中的高级搜索功能有哪些? #学习方法#微信#经验分享

学习和考试是大学生生活中不可避免的一部分&#xff0c;而在这个信息爆炸的时代&#xff0c;如何快速有效地获取学习资源和解答问题成为了大学生们共同面临的难题。为了解决这个问题&#xff0c;搜题和学习软件应运而生。今天&#xff0c;我将为大家介绍几款备受大学生青睐的搜…

Python魔法方法 单例模式

前言 本文介绍一下python中常用的魔法方法以及面向对象中非常重要的单例模式。 魔法方法 python中一切皆对象&#xff0c;因为python是面向对象的编程语言。python给类和对象提供了大量的内置方法&#xff0c;这些内置方法也称魔法方法。这些魔法方法总是在某种条件下自动触…

探索设计模式的魅力:创建型设计模式的比较与决策

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 一、设计模式概览 1.1 创建型模式 二、比较创建型设计模式 1.1 适用场景典型用例 1.2 关键要素与差异对比 1.3 结构图 三、模式选择指南 3.1 场景分析 3.2 决策流程图 四、结语 4.1 优势 4.2 考量因素 一、…

node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查

文章目录 ⭐前言⭐ 功能设计与实现💖 node后端操作数据库实现增删改查💖 vue3前端实现增删改查⭐ 效果⭐ 总结⭐ 结束⭐结束⭐前言 大家好,我是yma16,本文分享关于 node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查。 技术选型 前端:vite+vue3+antd 后端:…

使用radial-gradient完成弧形凹陷的绘制

1、效果如下图 我在微信小程序中制作的 2、代码如下 <style>.header {position: relative;width: 200px;height: 200px;overflow: hidden;}.header .circle {--circleValue: 500px;position: absolute;bottom: 0;left: 50%;width: 100%;height: var(--circleValue);trans…