所有的进程都是通过它的父进程来创建的。因此,运行起来的python程序也是一个进程,那么我们也可以在程序中再创建进程。多个进程可以实现并发效果,也就是说,当我们的程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快
multiprocess模块
multiprocess不是一个模块而是python中一个操作、管理进程的包,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆,我将这部分大致分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享。
Process 创建进程的类
由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
强调:
windows创建进程会将代码以模块的方式,从上往下执行一遍,linux会直接将代码完完整整的拷贝一份
创建进程就是在内存中重新开辟了一块内存空间,将运行产生的代码丢进去,一个进程对应在内存就是一块独立的内存空间
进程与进程之间的数据时隔离的,无法直接交互,但是可以通过某些技术实现间接交互
语法
from multiprocessing import Process
代码块...
代码块...
代码块...
...
if __name__ == __main___: #
p = Process(target=调用对象, args=调用对象的位置参数元组) # 创建一个进程对象
代码块
p.start() # 告诉操作系统帮你创建一个进程
注意: windows创建进程一定要在 if __name__ == __main___: 代码块内创建,否则会报错
参数介绍
Process源码:
class Process(object):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
...
# group参数未使用,值始终为None
# target表示调用对象,即子进程要执行的任务
# args表示调用对象的位置参数元组,如:args=(1,2,'xxx',)
# kwargs表示调用对象的字典,kwargs={'name':'xxx','age':18}
# name为子进程的名称
方法介绍
- p.start():创建启动进程,并调用该子进程中的p.run()
- p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
- p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
- p.is_alive():如果p仍然运行,返回True
- p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
Process类创建进程的两种方式
# 开进程方法一:
from multiprocessing import Process
import time
def func(name):
print('%s running'%name)
time.sleep(3)
print('over')
print('w')
if __name__ == '__main__':
# 创建进程对象
p = Process(target=func, args=('waller',)) # target=func 是在p进程内存空间中调用执行了 func 函数 ,将函数注册到一个进程中,p是一个进程对象,此时还没有启动进程,只是创建了一个进程对象。并且func是不加括号的,因为加上括号这个函数就直接运行了对吧。
print('v')
p.start() # 启动p进程
# 告诉操作系统创建一个进程,开辟p进程的内存空间,func这个函数就被我们新开的这个进程执行了,而这个进程是我主进程运行过程中创建出来的,所以称这个新创建的进程为主进程的子进程,而主进程又可以称为这个新进程的父进程。
#start并不是直接就去执行了,我们知道进程有三个状态,进程会进入进程的三个状态,就绪,(被调度,也就是时间片切换到它的时候)执行,阻塞,并且在这个三个状态之间不断的转换,等待cpu执行时间片到了
print('主进程') # 异步
>>>
w
v
主进程
w
waller running
over
# 开进程方法二:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, name):
super(MyProcess, self).__init__()
self.name = name
def run(self):
print('%s running'%self.name)
time.sleep(3)
print('over')
if __name__ == '__main__':
p = MyProcess('waller')
p.start() # 自动运行 run 方法
print('主进程')
注意:
在Windows操作系统中由于没有fork(linux操作系统中创建进程的机制),在创建子进程的时候会自动 import 启动它的这个文件,而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子进程的部分使用if __name ==‘__main’ 判断保护起来,import 的时候 ,就不会递归运行了。