import multiprocessing
import logging
import importlib
importlib.reload(logging)
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s [%(processName)s] %(message)s')
# 环境(包配置)
多进程与多线程差不多:
p = multiprocessing.Process(target=worker, name='worker')
p.start()
<<2017-03-12 11:12:01,028 INFO [worker] worker
与多线程不同的:
p.pid # 进程唯一标识符pid
25951
p.exitcode # 进程退出
0
p.terminate() # 杀死进程
# 每个进程会启动一个解释器,所以进程的代价比线程要高
通讯方式不一样
由于多进程跨解释器的,所以进程的通讯 数据需要序列化
GIL对多进程无效,内置容器不是进程安全的,queue.Queue也不是进程安全的
Manager管理(wait_change)
from multiprocessing import Manager
mgr = Manager()
d = mgr.dict()
mgr.list()
<ListProxy object, typeid 'list' at 0x7fde504d1be0>
mgr.Namespace()
<NamespaceProxy object, typeid 'Namespace' at 0x7fde504d1d30>
ns = mgr.Namespace()
ns.f = 3
# 多进程环境,尽量避免数据交互。数据经过序列号和反序列号,有代价
# master -> worker模式交互数据
多线程和多进程的选择
- CPU密集型用多进程,可以充分利用CPU
- IO密集型用多线程,减少序列号/反序列化
请求/应答 这种模型,更多时候是结合使用的
通常由master进程接收请求,分发给多个worker进程处理,worker中再用线程来进一步分发
线程池(change_wait) to multiThread