1.先来简略了解下多进程
以下为简单例子和介绍
//
#单核cpu实现多任务原理,操作系统让各个任务交替执行
#多核cpu执行多任务, 如果任务跟核数一样,就一个核执行一个任务,如果任务多就跟单核一样
#并发与并行
#一个进程可以有多个线程,线程内部还有多个协程
#进程是程序的实体,打开浏览器是一个进程,打开两个记事本是两个进程
#进程创建 python
# python在linux下可以使用fork函数 fork()是内置函数,隶属于os模块
# python在Windows下引用multiprocessing 模块中的Process类创建新的进程
#创建进程的语法结构 Process(target=函数,name=进程的名字,args=给函数传递的参数,kwargs=关键字参数)
# 对象调用方法
#process.start() 启动子进程并执行任务
#process.run() 只是执行了任务但是没有启动子进程
#terminate() 终止
#父进程结束后,子进程也会继续执行,但是在多线程中即使进程结束后,线程也会存在直到线程执行完,
#进程常应用于图像并存处理,并行下载 ,但是下载一个文件不用多进程,他用多线程
##父进程与子进程执行的先后顺序
'''
父进程一定先执行
一旦启动子进程,后续的代码就并发,没有先后顺序
如果父进程需要等待子进程结束后才能执行
'''
##僵尸进程与孤儿进程
'''
僵尸进程:
一个进程任务执行完就死亡了,但是操作系统不会立即将其清理,为的是开启这个子进程的父进程可以访问到这个子进程的信息
孤儿进程 :
一个父进程已经死亡,然而他的子进程还在执行,这时候操作系统会接管这些孤儿进程
'''
//
from multiprocessing import Process
import time
import os
def task1():
for i in range(2):
time.sleep(0.5)
print('task1正在运行',os.getpid(),'------',os.getppid()) #os.getpid() 获取当前进程的编号 os.getppid()是父进程的编号
def task2():
for i in range(2):
time.sleep(0.5)
print('task2正在运行',os.getpid())
if __name__ == '__main__':
p1 = Process(target=task1)
p1.run() #run方法,跟p1()效果一样,会一直执行p1直到p1结束
p2 = Process(target=task2) #task1正在运行
p2.run() #task1正在运行
print('--------------下边是start,我是父进程不被if __name__ ==' '保护的代码---------------------') #为什么会出现三次这个呢,这是因为父进程被复制进子进程了
if __name__ == '__main__':
print('主进程的编号是:',os.getpid())
#主进程进行到Process后,创建一个子进程,然后主进程继续向下读取,子进程也开始运行
p1 = Process(target=task1,name='任务一') # Process开启的任务都是子进程 ,他们都是在python解释器这个主进程下开辟的子进程
print(p1.name)
p1.start()
print(p1.name) #start方法,才是真正利用多进程,p1.start 与p2.start 同时运行
p2 = Process(target=task2,name='任务二') #task1正在运行 #task2正在运行
p2.start()
print(p2.name)
print('---------------------父进程结束了---------------------------')
# Process() def __init__(self, group=None, target=None, name=None, args=(), kwargs={},
# *, daemon=None):
结果为
task1正在运行 21092 ------ 5820
task1正在运行 21092 ------ 5820
task2正在运行 21092
task2正在运行 21092
--------------下边是start,我是父进程不被if __name__ ==保护的代码---------------------
主进程的编号是: 21092
任务一
任务一
任务二
---------------------父进程结束了---------------------------
--------------下边是start,我是父进程不被if __name__ ==保护的代码---------------------
---------------------父进程结束了---------------------------
--------------下边是start,我是父进程不被if __name__ ==保护的代码---------------------
---------------------父进程结束了---------------------------
task1正在运行 17288 ------ 21092
task2正在运行 19204
task2正在运行 19204
task1正在运行 17288 ------ 21092
2.多进程之terminate 终止
//
from multiprocessing import Process
import time
import os
#进程会在不同的内存里处理,所以不共享变量
m=1 #查看多线程是否共享公共变量 ,发现他并不共享,这是因为每创建一个子进程,父进程都会复制进各个子进程中
def task1():
global m
while True:
time.sleep(1)
m+=1
print('task1正在运行',os.getpid(),'------',m) #os.getpid() 获取当前进程的编号 os.getppid()是父进程的编号
def task2():
global m
while True:
time.sleep(2)
m+=1
print('task2正在运行',os.getpid(),'-------------',m)
if __name__ == '__main__':
print('主进程的编号是:',os.getpid())
#主进程进行到Process后,创建一个子进程,然后主进程继续向下读取,子进程也开始运行
p1 = Process(target=task1,name='任务一')
p1.start()
p2 = Process(target=task2,name='任务二') #task1正在运行 #task2正在运行
p2.start()
number=0
while True:
number+=1
time.sleep(0.2)
if number==20:
p1.terminate()
p2.terminate()
break
else:
print(number)
结果为
主进程的编号是: 25180
1
2
3
4
5
task1正在运行 24756 ------ 2
6
7
8
9
10
task1正在运行 24756 ------ 3
task2正在运行 23640 ------------- 2
11
12
13
14
15
task1正在运行 24756 ------ 4
16
17
18
19
3.多进程之带参
//
from multiprocessing import Process
import time
import os
def task1(s,name):
for i in range(2):
time.sleep(s)
print('task1正在运行',os.getpid(),'------',os.getppid(),' ',name) #os.getpid() 获取当前进程的编号 os.getppid()是父进程的编号
def task2(s,name):
for i in range(2):
time.sleep(s)
print('task2正在运行',os.getpid(),'-------------',os.getppid(),' ',name)
if __name__ == '__main__':
print('主进程的编号是:',os.getpid())
#主进程进行到Process后,创建一个子进程,然后主进程继续向下读取,子进程也开始运行
p1 = Process(target=task1,name='任务一',args=[2,'aa',]) # Process开启的任务都是子进程 ,他们都是在python解释器这个主进程下开辟的子进程
print(p1.name) #注意,传参时必须是可迭代的,列表元组都可,而且还需要加上逗号
p1.start()
print(p1.name) #start方法,才是真正利用多进程,p1.start 与p2.start 同时运行
p2 = Process(target=task2,name='任务二',args=(2,'bb',)) #task1正在运行 #task2正在运行
p2.start()
print(p2.name)
结果为
主进程的编号是: 25012
任务一
任务一
任务二
task1正在运行 3012 ------ 25012 aa
task2正在运行 20904 ------------- 25012 bb
task1正在运行 3012 ------ 25012 aa
task2正在运行 20904 ------------- 25012 bb
4.自定义进程
//
#进程: 自定义
from multiprocessing import Process
class MyProcess(Process):
#只要是自定义进程和线程,都需要重写run
def run(self):
print('进程名字:'+self.name) #继承了Process,所以他可以继承name,又因为在初始子进程中,无法访问self.name,
# 但是我又想访问name,所以我就重写了了Process
print('-------->自定义进程')
def __init__(self,name,i):
super(MyProcess,self).__init__(name=name,args=(i,))
#self.name=name
if __name__ == '__main__':
p1=MyProcess('小红',2)
p1.start()
p2=MyProcess('小明',2)
p2.start()
结果为
进程名字:小红
-------->自定义进程
进程名字:小明
-------->自定义进程