python模块-多进程

概述

  • [x] 多进程概念
  • [x] 多进程的Process
  • [x] 多进程的Pool
  • [x] 多进程的Pool相关函数
  • [x] 基于队列的多进程

多进程概念

顾名思义,多进程就是多个进程,可以并发执行任务,从而提高效率,在python中,因为全局锁的原因,对于CPU密集的任务,多线程起不到任何的作用,反而会因为线程切换,而导致效率下降。而多进程可以解决这个问题。

多进程一般有两种实现方式

  1. Process
  2. Pool

多进程的Process

首先先上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
from multiprocessing import Process
import os
from datetime import datetime
def run_proc(name):
print('Child process {0} is running'.format(name,os.getpid()))
if __name__ == "__main__":
print('parent process {} is running'.format(os.getpid()))
for i in range(5):
p = Process(target=run_proc,args=(str(i),))
print('process start {}'.format(datetime.now()))
p.start()
p.join()
print('close')

很简单的代码示例,跟多线程有点像。

多进程的Pool

有时候进程开的太多容易使得程序崩溃。这个时候可以通过进程池来解决这个问题,如果启动的进程达到了池子里面的数量,就会先执行当前的进程,执行完一个再放进来一个。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
#-*-coding:utf-8-*-
# Pool 指定数量的进程,默认是CPU数量,如果池子没有满,就创建一个新进程,否则就等待
# apply_async 允许多个进程进入池子进行执行
# apply 只允许一个进程

from multiprocessing import Process,Pool
import os
from datetime import datetime
import time

def run_proc(i):
time.sleep(10)
print('[process {}]I am child process {} and the start time is {}'.format(i,os.getpid(),datetime.now()))
time.sleep(10)
print('task done')

if __name__ == "__main__":
p = Pool(processes=os.cpu_count())
for i in range(10):
p.apply_async(run_proc,args=(str(i),))
#p.apply(run_proc,args=(str(i),))
p.close()
p.join()
print('all done')

多进程的Pool相关函数

start()

启动进程

join()

跟多线程一样,使用了join函数,会使得主进程等待子进程结束才会结束,否则就会提前结束

name

这不是函数,是一个属性,指的是进程的名字

is_alive()

检查进程是否存活,除非进程terminates了。

close()

close函数必须要在join函数前面,调用了close函数以后,就不能再添加进程了。这里的close指的是关闭进程池。在Pool里面一定要关闭进程池,而且必须要在join面前,要不执行不了。找不到更多的解释,估计很多人也是一知半解。

terminate

结束当前的进程,不在处理

基于队列的多进程

一个简单的多进程队列例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from multiprocessing import Queue,Pool,Process

# 使用队列进行多进程

def producer(q):
for i in range(20):
q.put(i)

def worker(q):
while not q.empty():
item = q.get()
print(item)

if __name__ == "__main__":
# 在这里加入队列
q=Queue()
producer(q)
for i in range(10):
p = Process(target=worker,args=(q,))
p.start()

p.join()
print("done")

但是需要注意的是,这里的Queue只适用于Process在,不适用于Pool