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

智能推荐

18个顶级人工智能平台-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏27次。来源:机器人小妹  很多时候企业拥有重复,乏味且困难的工作流程,这些流程往往会减慢生产速度并增加运营成本。为了降低生产成本,企业别无选择,只能自动化某些功能以降低生产成本。  通过数字化..._人工智能平台

electron热加载_electron-reloader-程序员宅基地

文章浏览阅读2.2k次。热加载能够在每次保存修改的代码后自动刷新 electron 应用界面,而不必每次去手动操作重新运行,这极大的提升了开发效率。安装 electron 热加载插件热加载虽然很方便,但是不是每个 electron 项目必须的,所以想要舒服的开发 electron 就只能给 electron 项目单独的安装热加载插件[electron-reloader]:// 在项目的根目录下安装 electron-reloader,国内建议使用 cnpm 代替 npmnpm install electron-relo._electron-reloader

android 11.0 去掉recovery模式UI页面的选项_android recovery 删除 部分菜单-程序员宅基地

文章浏览阅读942次。在11.0 进行定制化开发,会根据需要去掉recovery模式的一些选项 就是在device.cpp去掉一些选项就可以了。_android recovery 删除 部分菜单

mnn linux编译_mnn 编译linux-程序员宅基地

文章浏览阅读3.7k次。https://www.yuque.com/mnn/cn/cvrt_linux_mac基础依赖这些依赖是无关编译选项的基础编译依赖• cmake(3.10 以上)• protobuf (3.0 以上)• 指protobuf库以及protobuf编译器。版本号使用 protoc --version 打印出来。• 在某些Linux发行版上这两个包是分开发布的,需要手动安装• Ubuntu需要分别安装 libprotobuf-dev 以及 protobuf-compiler 两个包•..._mnn 编译linux

利用CSS3制作淡入淡出动画效果_css3入场效果淡入淡出-程序员宅基地

文章浏览阅读1.8k次。CSS3新增动画属性“@-webkit-keyframes”,从字面就可以看出其含义——关键帧,这与Flash中的含义一致。利用CSS3制作动画效果其原理与Flash一样,我们需要定义关键帧处的状态效果,由CSS3来驱动产生动画效果。下面讲解一下如何利用CSS3制作淡入淡出的动画效果。具体实例可参考刚进入本站时的淡入效果。1. 定义动画,名称为fadeIn@-webkit-keyf_css3入场效果淡入淡出

计算机软件又必须包括什么,计算机系统应包括硬件和软件两个子系统,硬件和软件又必须依次分别包括______?...-程序员宅基地

文章浏览阅读2.8k次。计算机系统应包括硬件和软件两个子系统,硬件和软件又必须依次分别包括中央处理器和系统软件。按人的要求接收和存储信息,自动进行数据处理和计算,并输出结果信息的机器系统。计算机是脑力的延伸和扩充,是近代科学的重大成就之一。计算机系统由硬件(子)系统和软件(子)系统组成。前者是借助电、磁、光、机械等原理构成的各种物理部件的有机组合,是系统赖以工作的实体。后者是各种程序和文件,用于指挥全系统按指定的要求进行..._计算机系统包括硬件系统和软件系统 软件又必须包括

随便推点

进程调度(一)——FIFO算法_进程调度fifo算法代码-程序员宅基地

文章浏览阅读7.9k次,点赞3次,收藏22次。一 定义这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。这里,我_进程调度fifo算法代码

mysql rownum写法_mysql应用之类似oracle rownum写法-程序员宅基地

文章浏览阅读133次。rownum是oracle才有的写法,rownum在oracle中可以用于取第一条数据,或者批量写数据时限定批量写的数量等mysql取第一条数据写法SELECT * FROM t order by id LIMIT 1;oracle取第一条数据写法SELECT * FROM t where rownum =1 order by id;ok,上面是mysql和oracle取第一条数据的写法对比,不过..._mysql 替换@rownum的写法

eclipse安装教程_ecjelm-程序员宅基地

文章浏览阅读790次,点赞3次,收藏4次。官网下载下载链接:http://www.eclipse.org/downloads/点击Download下载完成后双击运行我选择第2个,看自己需要(我选择企业级应用,如果只是单纯学习java选第一个就行)进入下一步后选择jre和安装路径修改jvm/jre的时候也可以选择本地的(点后面的文件夹进去),但是我们没有11版本的,所以还是用他的吧选择接受安装中安装过程中如果有其他界面弹出就点accept就行..._ecjelm

Linux常用网络命令_ifconfig 删除vlan-程序员宅基地

文章浏览阅读245次。原文链接:https://linux.cn/article-7801-1.htmlifconfigping <IP地址>:发送ICMP echo消息到某个主机traceroute <IP地址>:用于跟踪IP包的路由路由:netstat -r: 打印路由表route add :添加静态路由路径routed:控制动态路由的BSD守护程序。运行RIP路由协议gat..._ifconfig 删除vlan

redux_redux redis-程序员宅基地

文章浏览阅读224次。reduxredux里要求把数据都放在公共的存储区域叫store里面,组件中尽量少放数据,假如绿色的组件要给很多灰色的组件传值,绿色的组件只需要改变store里面对应的数据就行了,接着灰色的组件会自动感知到store里的数据发生了改变,store只要有变化,灰色的组件就会自动从store里重新取数据,这样绿色组件的数据就很方便的传到其它灰色组件里了。redux就是把公用的数据放在公共的区域去存..._redux redis

linux 解压zip大文件(解决乱码问题)_linux 7za解压中文乱码-程序员宅基地

文章浏览阅读2.2k次,点赞3次,收藏6次。unzip版本不支持4G以上的压缩包所以要使用p7zip:Linux一个高压缩率软件wget http://sourceforge.net/projects/p7zip/files/p7zip/9.20.1/p7zip_9.20.1_src_all.tar.bz2tar jxvf p7zip_9.20.1_src_all.tar.bz2cd p7zip_9.20.1make && make install 如果安装失败,看一下报错是不是因为没有下载gcc 和 gcc ++(p7_linux 7za解压中文乱码