Python多进程与多线程
1. fork():
这个是Unix/Linux操作系统提供一个fork操作:操作系统自动把当前进程(称为父进程)复制了一份(称之为子进程),然后分别在父进程和子进程中返回。子进程返回的永远是0,父进程返回的是子进程的ID,子进程只需要getppid() 就可以拿到父进程的ID。
有了fork操作就可以复制一个子进程来处理新任务,常见的Apache服务器就是由父进程监听端口,每当有http请求的时候,就fork出来子进程处理新的http请求。
multiprocessing---跨平台版本的多进程模块
2. Process类(启动少量的进程对象)
from multiprocessing import Process
p = Process(target = run_processing, args = ('test',))
p.start() # 开启进程
p.join() # 等待子进程结束之后再继续运行下去,主要用于进程间的同步
创建一个Process实例,用start方法启动,这样创建进程比fork更简单
3. Pool(启动多数的进程对象)
进程池,如果要启动大量的进程,推荐使用进程池的方式。
from multiprocessing import Pool
p = Pool()
for i in rnage(5):
p.apply_async(long_time, args = (i,))
p.close()
p.join()
对Pool对象调用join()方法会等待所有子进程执行完毕,
调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
进程间通信 Queue | Pips
Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
在Unix/Linux下,multiprocessing
模块封装了fork()
调用,使我们不需要关注fork()
的细节。由于Windows没有fork
调用,因此,multiprocessing
需要“模拟”出fork
的效果,父进程所有Python对象都必须通过pickle序列化再传到子进程去,所有,如果multiprocessing
在Windows下调用失败了,要先考虑是不是pickle失败了。
from multiprocessing import Process, Queue
import os, time, random
# 写数据进程执行的代码:
def write(q):
for value in ['A', 'B', 'C']:
print 'Put %s to queue...' % value
q.put(value)
time.sleep(random.random())
# 读数据进程执行的代码:
def read(q):
while True:
value = q.get(True)
print 'Get %s from queue.' % value
if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()