在python中有一个multiprocessing的模块,该模块提供了一个Process类创建进程对象。因此,需要使用多进程的时候,需要导入这个包。如下:
代码语言:javascript复制from multiprocessing import Process #导入模块
下面是一个例子,非常简单。注释里面写的也是非常清楚的。
代码语言:javascript复制from multiprocessing import Process #导入多进程模块
def child1(): #实现子进程功能的函数
print("子进程")
def child2(num):
print(num)
def child3(num,age):
print(num,age)
if __name__ == "__main__": #这行语句在Windows下执行python多进程的时候必须加上,Linux可以不需要。
'''
在Windows下子进程会自动import启动它的文件,这就导致,在Windows下如果不加这句,那么子进程会循环创建它本身,导致子进程出现问题。
所以,创建子进程的语句必须被这个if给包含起来。这也意味着程序会从这里开始执行。
__name__ 是属于 python 中的内置类属性,就是它会天生就存在于一个 python 程序中,代表对应程序名称。
当我们在运行这个代码时这个代码的 __name__ 的值为 __main__
当自己作为模块被调用时就是自己的名字
'''
p1 = Process(target=child1,name="简单的进程") #创建进程对象,target参数是指定实现子进程功能的函数;name参数是指定子进程名字。
p2 = Process(target=child2,name="打印数字进程",args=(123,)) #args参数的内容将会被传递给target指定的函数。注意args是一个元组。当你只有一个参数的时候,那么需要加上逗号。
p3 = Process(target=child3,name="多参数子进程",args=(456,18))
p1.start() #启动子进程,把进程加入到就绪队列中,等待系统调度机制来调用该进程。
p2.start()
p3.start()
p1.join() #父进程等待子进程结束,如果不使用join(),那么父进程将不会等待子进程。
p2.join() #join还有一个timeout参数,可以设置等待子进程的时长。
p3.join()
#进程名称对于程序员而言是有用的,但是对于操作系统而言是无意义的,操作系统用来唯一标识一个进程的标志是pid
print(p1.name) #打印子进程名字。
print(p2.name)
print(p3.name)
print(p1.pid) #打印pid
print(p2.pid)
print(p3.pid)
执行程序结果如下:
Python的全局变量在多个进程中是不共享的,进程之间的数据是独立的。这也符合进程这个概念。下面来看一个例子。
代码语言:javascript复制from multiprocessing import Process
num = 0
def child1():
global num #global表明使用全局的num变量
num = -1
print(num)
def child2():
global num
num = 1
print(num)
if __name__ == "__main__":
p1 = Process(target=child1,name="child1")
p2 = Process(target=child2,name="child2")
p1.start()
p2.start()
p1.join()
p2.join()
print(num)
执行结果如下:
当然了,你也可以继承Process类来实现自己的进程类,从而实现多进程。例如下面的例子:
代码语言:javascript复制from multiprocessing import Process
class MyProcess(Process):
def run(self):
print("这是新进程")
if __name__ == "__main__":
p = MyProcess()
p.start()
需要说明的是,当你继承Process类之后,必须重写run函数,而run函数制作的内容就是你子进程执行的代码,start()函数会去调用run函数,从而启动一个新的进程。当你需要参数的时候,那么这个类需要一个自定义的初始化函数__init__()。
Python的multiprocessing模块还提供了Pool来创建进程池,它能方便我们创建十几个或者上百个进程。
代码语言:javascript复制from multiprocessing import Pool
import time
def task(num):
print(num)
time.sleep(3)
if __name__ == "__main__":
p = Pool(5) #创建进程池,并切并发5个进程。
for i in range(30): #循环创建30个进程,但是每次只同时并发5个进程。
p.apply_async(task, args=(i,))
print("等待结束")
p.close() #关闭进程池
p.join() #join必须放在close后面。
print("结束")