多进程面试题汇总


在这里插入图片描述

这里写目录标题

  • 一、多进程
    • 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 Process


def 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 Process

class MyProcess(Process):
    """
    这是定义一个自己的进程类
    """
    def __init__(self,name):
        super().__init__()
        self.name=name

    def 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, Pool


def 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 += 1
    q.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应用。


在这里插入图片描述

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

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

相关文章

《合成孔径雷达成像算法与实现》FIgure6.20

% rho_r c/(2*Fr)而不是rho_r c/(2*Bw) % Hsrcf exp函数里忘记乘pi了 clc clear close all参数设置 距离向参数设置 R_eta_c 20e3; % 景中心斜距 Tr 2.5e-6; % 发射脉冲时宽 Kr 20e12; % 距离向调频率 alpha_os_r 1.2; …

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

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

[office] Excel CHITEST 函数 使用实例教程 #媒体#知识分享#其他

Excel CHITEST 函数 使用实例教程 提示 此函数已由 CHISQ.TEST 函数替换,新函数可以提供更好的精确度,其名称更好地反映其用法。旧函数仍可用于与早期版本Excel 的兼容。但是,如果不需要向后兼容,那么应考虑直接使用新函数&…

pands常用操作

1.导入库和文件读取和文件分信息分析 import pandas as pd import numpy as np csvf pd.read_csv(D:/各个站程序版本说明.csv) csvf.info() <class pandas.core.frame.DataFrame> RangeIndex: 51 entries, 0 to 50 Data columns (total 6 columns):# Column Non-Nul…

HTML5 Canvas与JavaScript携手绘制动态星空背景

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>星空背景</title> </head> <body style"overflow-x:hidden;"><canvas …

[职场] 会计学专业学什么 #其他#知识分享#职场发展

会计学专业学什么 会计学专业属于工商管理学科下的一个二级学科&#xff0c;本专业培养具备财务、管理、经济、法律等方面的知识和能力&#xff0c;具有分析和解决财务、金融问题的基本能力&#xff0c;能在企、事业单位及政府部门从事会计实务以及教学、科研方面工作的工商管…

optuna,一个好用的Python机器学习自动化超参数优化库

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️付费专栏:Python专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前言 超参数优化是机器学习中的重要问题,它涉及在训练模型时选择最优的超参数组合,以提高模型的性能和泛化能力。Optuna是一个用于自动化超参数优化的…

第五篇【传奇开心果系列】Python微项目技术点案例示例:中文有声故事书

传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目目标和背景二、雏形示例代码三、扩展思路四、用户自定义输入示例代码五、故事选择示例代码六、语音控制示例代码七、播放控制示例代码八、文本转换语音示例代码九、微项目雏形核心部分示例代…

【MySQL】操作库 —— 表的操作 -- 详解

一、增加表 1、创建表 mysql> create database [if not exists] table_name ( -> field1 datatype, -> field2 datatype, -> field3 datatype -> ) character set 字符集 collate 校验规则 engine 存储引擎; 注意 &#xff1a;最后一行也可以写成&#x…

枚举知识点解析

枚举是什么&#xff1f;枚举就是列举&#xff0c; 将东西一一列举出来。 生活中有许多地方需要用到枚举&#xff0c; 比如一年有12个月&#xff0c;一星期有7天&#xff0c; 这些都需要进行枚举。 那么&#xff0c; 如何进行枚举的定义呢&#xff1f; 如下 枚举中的值是一种…

【教3妹学编程-算法题】将数组分成最小总代价的子数组 I

2哥 : 叮铃铃&#xff0c;3妹&#xff0c;过年干嘛呢&#xff0c;是不是逛吃逛吃&#xff0c;有没有长胖呢。 3妹&#xff1a;切&#xff0c;我妈张罗着要给我相亲呢。 2哥 : 相亲&#xff1f;哈哈哈哈 3妹&#xff1a;别笑了&#xff0c;我妈说跟我年龄相等的人都已经孩子上小…

BossPlayerCTF

靶场环境问题 靶场下载之后&#xff0c;可能会出现扫描不到IP的情况&#xff0c;需要进行调整&#xff0c;参考&#xff1a; Vulnhub靶机检测不到IP地址_vulnhub靶机nmap扫不到-CSDN博客 该靶机没有vim&#xff0c;需要使用vi命令去修改&#xff1b;改成当前网卡即可&#x…

【QT+QGIS跨平台编译】之四十:【gsl+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、GSL介绍二、GSL下载三、文件分析四、pro文件五、编译实践一、GSL介绍 GSL(GNU Scientific Library)是一个开源的数值计算库,用于提供一系列常用的数学函数和算法。它为科学计算和数据分析提供了高效、可靠的工具。 GSL库提供了丰富的功能,包括数值积分、数值…

[职场] 事业单位医疗岗常见的面试题目 #微信#微信#微信

事业单位医疗岗常见的面试题目 面试是步入社会以及就业过程中必须经历的一个首要阶段&#xff0c;也是实现就业必经的之道&#xff0c;可以说面试是双向选择和考试考核评价的过程&#xff0c;是企业选择应聘者的同时也应聘者也在选择企业。 一.常见的面试题目 1.对医学基础知…

每日OJ题_递归②_力扣21. 合并两个有序链表

目录 力扣21. 合并两个有序链表 解析代码 力扣21. 合并两个有序链表 21. 合并两个有序链表 难度 简单 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4]…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第二套(完善程序题)

CCF认证CSP-J入门组模拟测试题第二套 三、完善程序题 第一题 菲波拉契数列 菲波拉契数列为1,1,2,3,5,8,13,21,…,其元素产生的规则是前两个数为1,从第三个数开始每个数等于它前面两个数之和。已知任意一个正整数可以表示为若干个互不相同的菲波拉契数之和。例如:3621132。 …

图像处理之《寻找和隐藏:通过深度强化学习的对抗隐写术》论文阅读

一、文章摘要 图像隐写术的目的是将一个完整大小的图像(称为秘密)隐藏到另一个图像(称为封面)中。以往的图像隐写算法只能在一个封面中隐藏一个秘密。在这篇论文中&#xff0c;我们提出了一个自适应局部图像隐写(AdaSteg)系统&#xff0c;允许缩放和位置自适应图像隐写。该系统…

2024.2.14

1.请编程实现二维数组的杨慧三角 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int n,i,j;printf("please enter n:");scanf("%d",&n);int arr[n][n];for(i0;i<n;i){for(j0;j<i;j){if(j0 || ij…

【无标题】Matlab 之axes函数——创建笛卡尔坐标区

**基本用法&#xff1a;**axes 在当前图窗中创建默认的笛卡尔坐标区&#xff0c;并将其设置为当前坐标区。 应用场景1&#xff1a;在图窗中放置两个 Axes 对象&#xff0c;并为每个对象添加一个绘图。 要求1&#xff1a;指定第一个 Axes 对象的位置&#xff0c;使其左下角位于…

【AIGC】Stable Diffusion的ControlNet插件

ControlNet 介绍 ControlNet 插件是 Stable Diffusion 中的一个重要组件&#xff0c;用于提供对模型的控制和调整。以下是 ControlNet 插件的主要特点和功能&#xff1a; 模型控制&#xff1a; ControlNet 允许用户对 Stable Diffusion 中的模型进行精细的控制和调整。用户可以…