(P9-P10)多进程multiprocessing模块
原创
©著作权归作者所有:来自51CTO博客作者喜欢打篮球的普通人的原创作品,请联系作者获取转载授权,否则将追究法律责任
文章目录
- 1.有了多线程threading,为什么还要用多进程multiprocessing
- 2.multiprocessin语法VS多线程threading语法
- 3.进程池在flask中的应用
- 4.os._exit() 和 sys.exit()
1.有了多线程threading,为什么还要用多进程multiprocessing
- 如果遇到了CPU密集型计算,多线程反而会降低执行速度!
虽然有全局解释器锁GIL,但是因为有IO的存在,多线程依然可以加速运行 
- CPU密集型计算,线程的自动切换反而变成了负担,多线程甚至减慢了运行速度

- multiprocessing模块就是python为了解决GIL缺陷引入的一个模块,原理是用多进程在多CPU上并行执行
2.multiprocessin语法VS多线程threading语法

- eg:判断一个数是否为素数,06. thread_process_cpu_bound.py
import math
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time
##很长的list
PRIMES = [112272535095293] * 100
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def single_thread():
for number in PRIMES:
is_prime(number)
def multi_thread():
with ThreadPoolExecutor() as pool:
pool.map(is_prime, PRIMES)
def multi_process():
with ProcessPoolExecutor() as pool:
pool.map(is_prime, PRIMES)
if __name__ == "__main__":
start = time.time()
single_thread()
end = time.time()
print("single_thread, cost:", end - start, "seconds")
start = time.time()
multi_thread()
end = time.time()
print("multi_thread, cost:", end - start, "seconds")
start = time.time()
multi_process()
end = time.time()
print("multi_process, cost:", end - start, "seconds")
3.进程池在flask中的应用
- eg:07. flask_process_pool.py
import flask
from concurrent.futures import ProcessPoolExecutor
import math
import json
app = flask.Flask(__name__)
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
##执行的时候,将将route中的<numbers>作为参数,传递到numbers这里面
@app.route("/is_prime/<numbers>")
def api_is_prime(numbers):
##numbers是一个字符串
number_list = [int(x) for x in numbers.split(",")]
results = process_pool.map(is_prime, number_list)
return json.dumps(dict(zip(number_list, results)))
if __name__ == "__main__":
##多进程与多线程写法上的区别:
##因为多进程他们环境之间是相互完全隔离的,在定义process_pool时,他所依赖使用的函数都必须得声明定义完毕
##所以process_pool必须放在所有依赖函数的最下面才可以使用
##然而多线程的定义放到哪都行
##在flask中使用多进程的方式,必须放到__main__下面,在app.run()之前初始化process_pool = ProcessPoolExecutor()
process_pool = ProcessPoolExecutor()
app.run()
4.os._exit() 和 sys.exit()
- Python的程序有两中退出方式:os._exit(), sys.exit()。本文介绍这两种方式的区别和选择。
- os._exit()会直接将python程序终止,之后的所有代码都不会继续执行。
- sys.exit()会引发一个异常:SystemExit,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获此异常的代码,那么这些代码还是会执行。捕获这个异常可以做一些额外的清理工作。0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获。
- sys.exit()的退出比较优雅,调用后会引发SystemExit异常,可以捕获此异常做清理工作。os._exit()直接将python解释器退出,余下的语句不会执行。
一般情况下使用sys.exit()即可,一般在fork出来的子进程中使用os._exit()
一般来说os._exit() 用于在线程中退出 。sys.exit() 用于在主线程中退出。
import os
try:
os._exit(0)
except:
print 'die.'
此处不会打出”die”
import sys
try:
sys.exit(0)
except:
print 'die'
finally:
print 'cleanup'
输出:
die
cleanup
- exit() 跟 C 语言等其他语言的 exit() 应该是一样的。
os._exit() 调用 C 语言的 _exit() 函数。 - exit(0)和exit(1)
exit(0):无错误退出
exit(1):有错误退出 - 参考:链接,os._exit() 和 sys.exit()