多线程编程>>>见上篇
什么时候用多进程编程?
由于 GIL锁,多线程无法充分多核优势。即在耗cpu时,多线程无法去并行.....
耗cpu的操作时,用多进程编程。如:计算,算法,图形处理...
耗io的操作时,用多线程编程(进程切换代价要高于线程)。如:爬虫时的等待.....
python os.fork()可以创建子进程(linux下)
eg:
import os
import time
pid = os.fork()
if pid == 0:
print("子进程为:{0}, 父进程为:{1}".format(os.getpid(),os.getppid()))
else:
print("父进程:{0}".format(pid))
time.sleep(5) # 可让子进程随父进程退出而kill掉,不然父进程先退出了子进程就不自动kill
说明:
此代码会运行父线程后,再运行子进程(从`pid = os.fork()`后运行)
(即会将`pid = os.fork()`后的所有代码及其数据全部拷贝到子进程中)
------------
多进程间通信:
注:进程间的数据完全隔离的。
因此,
在多线程中的`共享全局变量`与`线程中的Queue`不再适用于多进程
1\\ 进程Queue
# 建立一个共享的队列(其实并不是共享的,实际是克隆的,内部维护着数据的共享),多个进程可以向队列里存/取数据
from multiprocessing import Queue
queue = Queue(7)
2\\ Pipe
# 进程间的管道内部机制通过启动socket连接来维护两个进程间的通讯
from multiprocessing import Pipe
son,father=Pipe() # 实例化管道,生成socket连接,一个客户端一个服务端
3\\ Manager
# Manager实现了多个进程间的数据共享
支持的数据类型有 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array
from multiprocessing import Manager # 其实例下的方法`Queue`
queue = Manager().Queue(7)
# 及其他数据类型
注: Python中有2个Queue, 不,应该说有3个
1\\ from queue import Queue
queue = Queue(3) # 普通Queue, 可用于多线程
2\\ from multiprocessing import Queue
queue = Queue(3) # 进程Queue, 可用于多进程(不可用于进程池)
3\\ from multiprocessing import Manager
queue = Manager().Queue(3) # 进程Queue, 可用于多进程,也可用于进程池
多进程与多线程代码编写很类似(注: win下不能直接运行多进程,要放于`if __name__ == "__main__":`下运行)
进程池有两种方式:
1\\ from multiprocessing import Pool
2\\ from concurrent.futures import ProcessPoolExecutor # 底层也是用`multiprocessing.Pool`实现的