Python中的多进程_python 某系统中有n个进程,每个进程都有自己唯一的进程id(pid),同时每个进程-程序员宅基地

技术标签: 程序员  python  互联网  

多进程:

程序:是一个指令的集合

进程:正在执行的程序,或者说当你运行一个程序,你就启动了一个进程。

--编写完的代码,没有运行时称为程序,正在运行的代码,称为进程。

--程序是死的(静态的)进程是活的(动态的)

操作系统轮流让各个任务交替执行,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。

多进程中,每个进程中所有数据(包括全局变量)都各自拥有一份,互不影响。

例如:我们启动了QQ,QQ就是一个主进程,在QQ运行过程中,我们分别打开了三个(和A B C同学的)聊天窗口,这时 每个窗口就是属于主进程下的一个子进程,我们和每个同学聊天的数据都各有一份,互不影响。

#模拟多任务处理:一边唱歌,一边跳舞
from time import sleep
def sing():
    for i in range(5):
        print("唱歌")
        dance()
        sleep(1)
def dance():
    print("跳舞")
sing()

程序开始运行时,首先会创建一个主进程,在主进程下,我们可以创建新的进程(子进程),子进程依赖于主进程,如果主进程结束,程序会退出。(例如:QQ运行过程中(主进程)我们打开了和多位好友的聊天窗口(子进程),和他们聊天,这时如果直接退出QQ,聊天窗口也会消失。)

Python提供了非常好用的多进程包multiprocessing,借助这个包,可以轻松完成从单进程到并发执行的转换。

multiprocessing模块提供了一个Process类来创建一个进程对象。

(也就是说Process类中把进程对象该有的特征都写入了,有了Process类,方便我们创建进程对象)

Process(target,name,args)

参数介绍:

-target 表示调用对象,即子进程要执行的任务

-args 表示调用对象的位置参数元组

-name 子进程的名称

from multiprocessing import Process
def run(name):
    print("子进程运行中,name=%s"%name)
    print("子进程结束")
    # print(a)
if __name__ == '__main__':
    print("父进程启动")
    # a = 1000
    p=Process(target=run,args=('test',),name='pro-1')
    #"="右边是创建的子进程对象,p是该对象的引用  name='pro-1'可以不写,系统会默认起名: Process-n(是第几个子进程就叫-几)
    #target表示调用对象,args表示调用对象的位置参数元组
    #注意:元组中只有一个元素时结尾要加,
    print("子进程将要执行")
    p.daemon=True  #是否设置为守护进程(主进程结束,子进程也结束)(如果主进程结束,子进程还在运行,那么这个子进程叫孤儿进程)
    p.start()#此时子进程运行,CPU中主进程和子进程频繁做切换
    #在子进程执行时有个问题:在Windows上,子进程执行时会自动import启动它的这个文件(主进程),而在import的时候是会执行这些语句的,
    #这些语句中包含了创建一个子进程对象,因此会导致递归(无限创建子进程)
    print(p.name)
    p.join()#此处join()的作用:让主进程等子进程执行完再退出(因为程序执行过程中如果主进程退出,此时子进程未执行完,也会退出)
    print("主进程结束")
'''
if __name__=='__main__':说明
一个Python的文件(模块)有两种使用的方法,第一是直接作为程序执行,
第二是被其他Python模块导入(import)调用执行(模块重用)
因此if __name__=='__main__':的作用就是控制这两种情况执行代码的过程,__name__是内置变量,用于表示当前模块的名字
(如果当前的文件作为程序直接执行,那么此时它的__name__就是__main)也就是说
在if __name__=='__main__':下的代码只有在文件作为程序直接执行时才会执行,而import到其他程序中是不会执行的
在Windows上,子进程会自动import启动它的这个文件,而在import的时候是会执行这些语句的,如果不加if __name__=='__main__':
的话就会无线递归创建子进程,所以必须把创建子进程的部分用那个if判断保护起来
import的时候如果__name__不是__main__,就不会递归运行了
'''

Process类常用方法:

—p.start() 启动进程,并调用该子进程中的p.run()

—p.run() 进程启动时运行的方法,正是它去调用target指定的函数

—p.terminate() 强制终止进程p,不会进行任何清理操作(了解即可)

进程强制终止后,进程对象仍然存在,但是此时你却不能调(因为已经强制终止了,不能再用start()了),此时的进程对象也被称为僵尸进程。

例如:如果程序有个限制:进程1执行完后才能执行进程2,此时把进程1强制终止,那么进程2永远也不能执行了。

—p.is_alive() 如果p仍然运行,返回True.用来判断进程是否还在运行

—p.join([timeout]):主进程等待p终止,timeout是可选的超时时间

Process类常用属性:

name:当前进程实例别名,默认为Pricess-N,N为从1开始递增的整数;

pid:当前进程实例的PID值(也就是当前的一个进程号)(只要有一个进程执行,系统就会给它分配一个PID,是系统用来分辨不同的进程用的)

全局变量在多个进程中不共享,进程之间的数据是独立的,默认情况下互不影响。

from multiprocessing import Process
num=1
def run1():
    global num
    num+=5
    print("子进程1运行中,num=%d"%num)
def run2():
    global num
    num+=10
    print("子进程2运行中,num=%d"%num)
if __name__ == '__main__':
    print("主进程启动")
    p1=Process(target=run1)
    p2=Process(target=run2)
    print("子进程将要执行")
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print("子进程结束")
#运行结果
主进程启动
子进程将要执行
子进程1运行中,num=6
子进程2运行中,num=11
子进程结束
1

创建新的进程还能够使用类的方式,可以自定义一个类,继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象.

import multiprocessing,time
class ClockProcess (multiprocessing.Process):
    def run(self):#重写run()方法
        n=5
        while n>0:
            print(n)
            time.sleep(1)
            n-=1
if __name__ == '__main__':
    p=ClockProcess()
    p.start()#启动进程并调用run()方法
    p.join()

进程池:

进程池:用来创建多个进程

当需要创建的⼦进程数量不多时, 可以直接利⽤multiprocessing中的Process动态生成多个进程, 但如果是上百甚⾄上千个⽬标,⼿动的去创建进程的⼯作量巨⼤,此时就可以⽤到multiprocessing模块提供的Pool

初始化Pool时,可以指定⼀个最⼤进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建⼀个新的进程⽤来执⾏该请求,但如果池中的进程数已经达到指定的最⼤值,那么该请求就会等待,直到池中有进程结束才会创建新的进程来执⾏.

from multiprocessing import Pool
import random,time
def work(num):
    print(random.random()*num)
    time.sleep(3)
if __name__ == '__main__':
    po=Pool(3)#定义一个进程池,最大进程数为3 默认大小为CPU核数
    for i in range(10):
        po.apply_async(work,(i,))#apply_async选择要调用的目标,每次循环会用空出来的子进程去调用目标
    po.close()#进程池关闭之后不再接受新的请求
    po.join()#等待po中所有子进程结束,语法规定:必须放在close后面
#在多进程中,主进程一般用来等待,真正的任务都在子进程中执行

multiprocessing.Pool常⽤函数解析:

–apply_async(func[, args[, kwds]]) : 使⽤⾮阻塞⽅式调⽤func(并⾏执⾏,堵塞⽅式必须等待上⼀个进程退出才能执⾏下⼀个进程)args为传递给func的参数列表,kwds为传递给func的关键字参数列表;

–apply(func[, args[, kwds]])(了解即可几乎不用) 使⽤阻塞⽅式调⽤func

–close():关闭Pool,使其不再接受新的任务;

–terminate():不管任务是否完成,⽴即终⽌;

join():主进程阻塞,等待⼦进程的退出, 必须在close或terminate之后 使⽤;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w17688977481/article/details/88581524

智能推荐

874计算机科学基础综合,2018年四川大学874计算机科学专业基础综合之计算机操作系统考研仿真模拟五套题...-程序员宅基地

文章浏览阅读1.1k次。一、选择题1. 串行接口是指( )。A. 接口与系统总线之间串行传送,接口与I/0设备之间串行传送B. 接口与系统总线之间串行传送,接口与1/0设备之间并行传送C. 接口与系统总线之间并行传送,接口与I/0设备之间串行传送D. 接口与系统总线之间并行传送,接口与I/0设备之间并行传送【答案】C2. 最容易造成很多小碎片的可变分区分配算法是( )。A. 首次适应算法B. 最佳适应算法..._874 计算机科学专业基础综合题型

XShell连接失败:Could not connect to '192.168.191.128' (port 22): Connection failed._could not connect to '192.168.17.128' (port 22): c-程序员宅基地

文章浏览阅读9.7k次,点赞5次,收藏15次。连接xshell失败,报错如下图,怎么解决呢。1、通过ps -e|grep ssh命令判断是否安装ssh服务2、如果只有客户端安装了,服务器没有安装,则需要安装ssh服务器,命令:apt-get install openssh-server3、安装成功之后,启动ssh服务,命令:/etc/init.d/ssh start4、通过ps -e|grep ssh命令再次判断是否正确启动..._could not connect to '192.168.17.128' (port 22): connection failed.

杰理之KeyPage【篇】_杰理 空白芯片 烧入key文件-程序员宅基地

文章浏览阅读209次。00000000_杰理 空白芯片 烧入key文件

一文读懂ChatGPT,满足你对chatGPT的好奇心_引发对chatgpt兴趣的表述-程序员宅基地

文章浏览阅读475次。2023年初,“ChatGPT”一词在社交媒体上引起了热议,人们纷纷探讨它的本质和对社会的影响。就连央视新闻也对此进行了报道。作为新传专业的前沿人士,我们当然不能忽视这一热点。本文将全面解析ChatGPT,打开“技术黑箱”,探讨它对新闻与传播领域的影响。_引发对chatgpt兴趣的表述

中文字符频率统计python_用Python数据分析方法进行汉字声调频率统计分析-程序员宅基地

文章浏览阅读259次。用Python数据分析方法进行汉字声调频率统计分析木合塔尔·沙地克;布合力齐姑丽·瓦斯力【期刊名称】《电脑知识与技术》【年(卷),期】2017(013)035【摘要】该文首先用Python程序,自动获取基本汉字字符集中的所有汉字,然后用汉字拼音转换工具pypinyin把所有汉字转换成拼音,最后根据所有汉字的拼音声调,统计并可视化拼音声调的占比.【总页数】2页(13-14)【关键词】数据分析;数据可..._汉字声调频率统计

linux输出信息调试信息重定向-程序员宅基地

文章浏览阅读64次。最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0)。因为后期要使用ttySAC0作为上层应用通信串口,所以要把所有的调试信息都给去掉。参考网上的几篇文章,自己做了如下修改,终于把调试信息重定向到ttySAC1上了,在这做下记录。参考文章有:http://blog.csdn.net/longt..._嵌入式rootfs 输出重定向到/dev/console

随便推点

uniapp 引入iconfont图标库彩色symbol教程_uniapp symbol图标-程序员宅基地

文章浏览阅读1.2k次,点赞4次,收藏12次。1,先去iconfont登录,然后选择图标加入购物车 2,点击又上角车车添加进入项目我的项目中就会出现选择的图标 3,点击下载至本地,然后解压文件夹,然后切换到uniapp打开终端运行注:要保证自己电脑有安装node(没有安装node可以去官网下载Node.js 中文网)npm i -g iconfont-tools(mac用户失败的话在前面加个sudo,password就是自己的开机密码吧)4,终端切换到上面解压的文件夹里面,运行iconfont-tools 这些可以默认也可以自己命名(我是自己命名的_uniapp symbol图标

C、C++ 对于char*和char[]的理解_c++ char*-程序员宅基地

文章浏览阅读1.2w次,点赞25次,收藏192次。char*和char[]都是指针,指向第一个字符所在的地址,但char*是常量的指针,char[]是指针的常量_c++ char*

Sublime Text2 使用教程-程序员宅基地

文章浏览阅读930次。代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大、灵活的编辑器,相信你和我一样,都不会例外。我用过的编辑器不少,真不少~ 但却没有哪款让我特别心仪的,直到我遇到了 Sublime Text 2 !如果说“神器”是我能给予一款软件最高的评价,那么我很乐意为它封上这么一个称号。它小巧绿色且速度非

对10个整数进行按照从小到大的顺序排序用选择法和冒泡排序_对十个数进行大小排序java-程序员宅基地

文章浏览阅读4.1k次。一、选择法这是每一个数出来跟后面所有的进行比较。2.冒泡排序法,是两个相邻的进行对比。_对十个数进行大小排序java

物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)_网络调试助手连接阿里云连不上-程序员宅基地

文章浏览阅读2.9k次。物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)其实作者本意是使用4G模块来实现与阿里云物联网平台的连接过程,但是由于自己用的4G模块自身的限制,使得阿里云连接总是无法建立,已经联系客服返厂检修了,于是我在此使用网络调试助手来演示如何与阿里云物联网平台建立连接。一.准备工作1.MQTT协议说明文档(3.1.1版本)2.网络调试助手(可使用域名与服务器建立连接)PS:与阿里云建立连解释,最好使用域名来完成连接过程,而不是使用IP号。这里我跟阿里云的售后工程师咨询过,表示对应_网络调试助手连接阿里云连不上

<<<零基础C++速成>>>_无c语言基础c++期末速成-程序员宅基地

文章浏览阅读544次,点赞5次,收藏6次。运算符与表达式任何高级程序设计语言中,表达式都是最基本的组成部分,可以说C++中的大部分语句都是由表达式构成的。_无c语言基础c++期末速成