创建进程的常用方式
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm=1001.2014.3001.5501
在Python中有多个模块可以创建进程,比较常用的有os.fork()函数、multiprocessing模块和Pool进程池。由于os.fork()函数只适用于Unix/Linux/Mac系统上运行,在Windows操作系统中不可用,所以本章重点介绍multiprocessing模块和Pool进程池这2个跨平台模块。
1 使用multiprocessing模块创建进程
multiprocessing模块提供了一个Process类来代表一个进程对象,语法如下:
Process([group [, target [, name [, args [, kwargs]]]]])
Process类的参数说明如下:
l group:参数未使用,值始终为None。
l target:表示当前进程启动时执行的可调用对象。
l name:为当前进程实例的别名。
l args:表示传递给target函数的参数元组。
l kwargs:表示传递给target函数的参数字典。
例如,实例化Process类,执行子进程,代码如下:
from multiprocessing import Process # 导入模块
# 执行子进程代码
def test(interval):
print('我是子进程')
# 执行主程序
def main():
print('主进程开始')
p = Process(target=test,args=(1,)) # 实例化Process进程类
p.start() # 启动子进程
print('主进程结束')
if __name__ == '__main__':
main()
运行结果如下:
主进程开始
主进程结束
我是子进程
注意:由于IDLE自身的问题,运行上述代码时,不会输出子进程内容,所以使用命令行方式运行Python代码,即在文件目录下,用“python + 文件名”方式,如图3所示。

图3 使用命令行运行python文件
上述代码中,先实例化Process类,然后使用p.start()方法启动子进程,开始执行test()函数。
Process的实例p常用的方法除start()外,还有如下常用方法:
l is_alive():判断进程实例是否还在执行。
l join([timeout]):是否等待进程实例执行结束,或等待多少秒。
l start():启动进程实例(创建子进程)。
l run():如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法。
l terminate():不管任务是否完成,立即终止。
Process类还有如下常用属性:
l name:当前进程实例别名,默认为Process-N,N为从1开始递增的整数。
l pid:当前进程实例的PID值。
![]()
实例01 创建两个子进程,并记录子进程运行时间
下面通过一个简单示例演示Process类的方法和属性的使用,创建2个子进程,分别使用os模块和time模块输出父进程和子进程的ID以及子进程的时间,并调用Process类的name和pid属性,代码如下:
# -*- coding:utf-8 -*-
from multiprocessing import Process
import time
import os
# 两个子进程将会调用的两个方法
def child_1(interval):
print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getppid()))
t_start = time.time() # 计时开始
time.sleep(interval) # 程序将会被挂起interval秒
t_end = time.time() # 计时结束
print("子进程(%s)执行时间为'%0.2f'秒"%(os.getpid(),t_end - t_start))
def child_2(interval):
print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getppid()))
t_start = time.time() # 计时开始
time.sleep(interval) # 程序将会被挂起interval秒
t_end = time.time() # 计时结束
print("子进程(%s)执行时间为'%0.2f'秒"%(os.getpid(),t_end - t_start))
if __name__ == '__main__':
print("------父进程开始执行-------")
print("父进程PID:%s" % os.getpid()) # 输出当前程序的PID
p1=Process(target=child_1,args=(1,)) # 实例化进程p1
p2=Process(target=child_2,name="mrsoft",args=(2,)) # 实例化进程p2
p1.start() # 启动进程p1
p2.start() # 启动进程p2
# 同时父进程仍然往下执行,如果p2进程还在执行,将会返回True
print("p1.is_alive=%s"%p1.is_alive())
print("p2.is_alive=%s"%p2.is_alive())
# 输出p1和p2进程的别名和PID
print("p1.name=%s"%p1.name)
print("p1.pid=%s"%p1.pid)
print("p2.name=%s"%p2.name)
print("p2.pid=%s"%p2.pid)
print("------等待子进程-------")
p1.join() # 等待p1进程结束
p2.join() # 等待p2进程结束
print("------父进程执行结束-------")
上述代码中,第一次实例化Process类时,会为name属性默认赋值为“Process-1”,第二次则默认为“Process-2”,但是由于在实例化进程p2时,设置了name属性为“mrsoft”,所以p2.name的值为“mrsoft”而不是“Process-2”。程序运行流程示意图如图4所示,运行结果如图5所示。

图4 运行流程示意图

图5 创建2个子进程
注意:读者运行时,进程的PID值会与图5不同,这与电脑有关,读者不必在意。
2 使用Process子类创建进程
对于一些简单的小任务,通常使用Process(target=test)方式实现多进程。但是如果要处理复杂任务的进程,通常定义一个类,使其继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象。下面,通过一个示例来学习一下如何通过使用Process子类创建多个进程。
![]()
实例02 使用Process子类创建两个子进程,并记录子进程运行时间
使用Process子类方式创建2个子进程,分别输出父、子进程的PID,以及每个子进程的状态和运行时间,代码如下:
# -*- coding:utf-8 -*-
from multiprocessing import Process
import time
import os
# 继承Process类
class SubProcess(Process):
# 由于Process类本身也有__init__初始化方法,这个子类相当于重写了父类的这个方法
def __init__(self,interval,name=''):
Process.__init__(self) # 调用Process父类的初始化方法
self.interval = interval # 接收参数interval
if name: # 判断传递的参数name是否存在
self.name = name # 如果传递参数name,则为子进程创建name属性,否则使用默认属性
# 重写了Process类的run()方法
def run(self):
print("子进程(%s) 开始执行,父进程为(%s)"%(os.getpid(),os.getppid()))
t_start = time.time()
time.sleep(self.interval)
t_stop = time.time()
print("子进程(%s)执行结束,耗时%0.2f秒"%(os.getpid(),t_stop-t_start))
if __name__=="__main__":
print("------父进程开始执行-------")
print("父进程PID:%s" % os.getpid()) # 输出当前程序的ID
p1 = SubProcess(interval=1,name='mrsoft')
p2 = SubProcess(interval=2)
# 对一个不包含target属性的Process类执行start()方法,就会运行这个类中的run()方法
# 所以这里会执行p1.run()
p1.start() # 启动进程p1
p2.start() # 启动进程p2
# 输出p1和p2进程的执行状态,如果真正进行,返回True;否则返回False
print("p1.is_alive=%s"%p1.is_alive())
print("p2.is_alive=%s"%p2.is_alive())
# 输出p1和p2进程的别名和PID
print("p1.name=%s"%p1.name)
print("p1.pid=%s"%p1.pid)
print("p2.name=%s"%p2.name)
print("p2.pid=%s"%p2.pid)
print("------等待子进程-------")
p1.join() # 等待p1进程结束
p2.join() # 等待p2进程结束
print("------父进程执行结束-------")
上述代码中,定义了一个SubProcess子类,继承multiprocess.Process父类。SubProcess子类中定义了2个方法:__init__()初始化方法和run()方法。在__init()__初识化方法中,调用multiprocess.Process父类的__init__()初始化方法,否则父类初始化方法会被覆盖,无法开启进程。此外,在SubProcess子类中并没有定义start()方法,但在主进程中却调用了start()方法,此时就会自动执行SubPorcess类的run()方法。运行结果如图6所示。

图6 使用Porcess子类创建进程
3 使用进程池Pool创建进程
在16.2.1小节和16.2.2小节中,我们使用Process类创建了2个进程。如果要创建几十个或者上百个进程,则需要实例化更多个Process类。有没有更好的创建进程的方式解决这类问题呢?答案就是使用multiprocessing模块提供的Pool类,即Pool进程池。
为了更好的理解进程池,可以将进程池比作水池,如图7所示。我们需要完成放满10个水盆的水的任务,而在这个水池中,最多可以安放3个水盆接水,也就是同时可以执行3个任务,即开启3个进程。为更快完成任务,现在打开3个水龙头开始放水,当有一个水盆的水接满时,即该进程完成1个任务,我们就将这个水盆的水倒入水桶中,然后继续接水,即执行下一个任务。如果3个水盆每次同时装满水,那么在放满第9盆水后,系统会随机分配1个水盆接水,另外2个水盆空闲。

图7 进程池示意图
接下来,先来了解一下Pool类的常用方法。常用方法及说明如下:
l apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func()函数(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func()函数的参数列表,kwds为传递给func()函数的关键字参数列表。
l apply(func[, args[, kwds]]):使用阻塞方式调用func()函数。
l close():关闭Pool,使其不再接受新的任务。
l terminate():不管任务是否完成,立即终止。
l join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用。
在上面的方法提到apply_async()使用非阻塞方式调用函数,而apply()使用阻塞方式调用函数。那么什么又是阻塞和非阻塞呢?在图8中,分别使用阻塞方式和非阻塞方式执行3个任务。如果使用阻塞方式,必须等待上一个进程退出才能执行下一个进程,而使用非阻塞方式,则可以并行执行3个进程。

图8 阻塞与非阻塞示意图
![]()
实例03 使用进程池创建多进程
下面通过一个示例演示一下如何使用进程池创建多进程。这里模拟水池放水的场景,定义一个进程池,设置最大进程数为3。然后使用非阻塞方式执行10个任务,查看每个进程执行的任务。具体代码如下:
# -*- coding=utf-8 -*-
from multiprocessing import Pool
import os, time
def task(name):
print('子进程(%s)执行task %s ...' % ( os.getpid() ,name))
time.sleep(1) # 休眠1秒
if __name__=='__main__':
print('父进程(%s).' % os.getpid())
p = Pool(3) # 定义一个进程池,最大进程数3
for i in range(10): # 从0开始循环10次
p.apply_async(task, args=(i,)) # 使用非阻塞方式调用task()函数
print('等待所有子进程结束...')
p.close() # 关闭进程池,关闭后p不再接收新的请求
p.join() # 等待子进程结束
print('所有子进程结束.')
运行结果如图9所示,从图9可以看出PID为11488的子进程执行了4个任务,而其余2个子进程分别执行了3个任务。

图9 使用进程池创建进程

相关文章:
创建进程的常用方式
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中有多个模块可以创建进程,比较常用的有os.fork()函数、multiprocessing模块和Pool进程池。由于os.fork()函数只适用于Unix/Linu…...
李宏毅2023机器学习作业HW06解析和代码分享
ML2023Spring - HW6 相关信息: 课程主页 课程视频 Sample code HW06 视频 HW06 PDF 个人完整代码分享: GitHub | Gitee | GitCode P.S. HW06 是在 Judgeboi 上提交的,出于学习目的这里会自定义两个度量的函数,不用深究,遵循 Sugge…...
专业技能篇--算法
文章目录 前言经典算法思想总结一、贪心算法二、动态规划三、回溯算法四、分治算法 前言 这篇简单理解一些常见的算法。如果面试的时候问到相关的算法,能够应付一二。 经典算法思想总结 一、贪心算法 思想:贪心算法是一种在每一步选择中都采取在当前状…...
Vue中CSS动态样式绑定
Vue中CSS动态样式绑定与注意事项_vue css动态绑定-CSDN博客 在 Vue 中,你不能直接在 CSS 中直接绑定 data 中的数据,因为 CSS 不是响应式的。但是,有几种方法可以实现根据 Vue 实例中的数据来动态地改变样式: 内联样式绑定&…...
【漏洞复现】契约锁电子签章平台 add 远程命令执行漏洞(XVE-2023-23720)
0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…...
计算机专业是否仍是“万金油”?
身份角度一:一名曾经的计算机专业学生 随着高考的结束,我站在了人生的分岔路口,面临着大学专业的选择。在众多的选择中,计算机专业一直是我深思熟虑后的一个重要选项。然而,我并不清楚自己是否真的适合这个专业&…...
Spring 启动顺序
在 Spring 框架中,应用启动过程涉及多个步骤和组件的初始化。理解 Spring 启动顺序不仅有助于优化应用性能,还能帮助开发人员排查启动过程中可能出现的问题。本文将详细介绍 Spring 启动过程中的关键步骤和顺序。 1. Spring 启动过程概述 Spring 应用的…...
2024.06.19 刷题日记
41. 缺失的第一个正数 这个题目的通过率很低,是一道难题,类似于脑筋急转弯,确实不好想。实际上,对于一个长度为 N 的数组,其中没有出现的最小正整数只能在 [1,N1] 中。 这个结论并不好想,举个例子&#x…...
linux系统中,pwd获取当前路径,dirname获取上一层路径;不使用 ../获取上一层路径
在实际项目中,我们通常可以使用 pwd 来获取当前路径,但是如果需要获取上一层路径,有不想使用 …/ 的方式,可以尝试使用 dirname指令 测试shell脚本 #!/bin/bash# 获取当前路径 CURRENT_PATH$PWD echo "CURRENT_PATH$CURREN…...
DeepSpeed Monitoring Comm. Logging
Monitoring 支持多种后端:Tensorboard、WandB、Comet、CSV文件; TensorBoard例子: 自动监控:DeepSpeed自动把重要metric记录下来。只需在配置文件里enable相应的看板后端即可: {"tensorboard": {"enabl…...
关于INCA的几个实用功能
01--VUI窗口设计 这个可以按照自己的想法设计INCA观测或标定窗口 首先进入到INCA的环境内,点击实验→加载VUI窗口 选择空的窗口 打开后如下所示: 点击UI开发模式,如下图 如下: 添加标定量、观测量、示波器 窗口的大小需要在开发…...
Mamaba3--RNN、状态方程、勒让德多项式
Mamaba3–RNN、状态方程、勒让德多项式 一、简单回顾 在Mamba1和Mamba2中分别介绍了RNN和状态方程。 下面从两个图和两个公式出发,对RNN和状态方程做简单的回顾: R N N : s t W s t − 1 U x t ; O t V s t RNN: s_t Ws_{t-1}Ux_t&…...
PLC模拟量和数字量到底有什么区别?
PLC模拟量和数字量的区别 在工业自动化领域,可编程逻辑控制器(PLC)是控制各种机械设备和生产过程的核心组件。PLC通过处理模拟量和数字量来实现对工业过程的精确控制。了解模拟量和数字量的区别对于设计高效、可靠的自动化系统至关重要。 1. …...
html中如何写一个提示框,css画一个提示框
在HTML中,提示框通常使用<div>元素来创建,然后使用CSS进行样式化。以下是一个示例,展示如何在HTML中写一个提示框,并使用CSS来设计其外观。 HTML 首先,创建一个HTML文件,其中包含一个提示框的结构&…...
ExoPlayer 学习笔记
https://www.51cto.com/article/777840.html ExoPlayer支持多种媒体格式和流媒体协议的播放器 播放视频:player.play()暂停视频:player.pause()停止播放:player.stop() Media3 ExoPlayer | Android media | Android Developers implem…...
汽车IVI中控开发入门及进阶(二十七):车载摄像头vehicle camera
前言: 在车载IVI、智能座舱系统中,有一个重要的应用场景就是视频。视频应用又可分为三种,一种是直接解码U盘、SD卡里面的视频文件进行播放,一种是手机投屏,就是把手机投屏软件已视频方式投屏到显示屏上显示,另外一种就是对视频采集设备(主要就是摄像头Camera)的视频源…...
Transformer模型:未来的改进方向与潜在影响
Transformer模型:未来的改进方向与潜在影响 自从2017年Google的研究者们首次提出Transformer模型以来,它已经彻底改变了自然语言处理(NLP)领域的面貌。Transformer的核心优势在于其“自注意力(Self-Attention…...
ROS 激光雷达
ROS 激光雷达 基本工作原理 激光雷达(LIDAR,Light Detection and Ranging)是一种用于测量距离的远程感应技术。它通过向目标发射激光并分析反射回来的光来测量目标与激光发射源之间的距离。激光雷达广泛应用于多种领域,包括地理…...
杂说咋说-关于城市化发展和城市治理的几点建议(浙江借鉴)
杂说咋说-关于城市化发展和城市治理的几点建议(浙江借鉴) 近年来,浙江省坚持一张蓝图绘到底,推动城市化发展和城市治理不断迈上新台阶,全省城市化水平和城市治理能力牢牢居于全国第一方阵。当前,国内外环境…...
Linux 常用命令 - which【定位可执行文件的位置】
简介 which 命令源自于英文单词 "which",用于在环境变量 PATH 所指定的路径中搜索某个可执行文件或链接(如一个系统命令)的位置,并返回第一个搜索结果。这个命令会遍历 PATH 环境变量中的所有路径,直到找到…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
