multiprocessing
如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork
调用,难道在Windows上无法用Python编写多进程的程序?
由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing
模块就是跨平台版本的多进程模块。
multiprocessing
模块提供了一个Process
类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束:
from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process
实例,用start()
方法启动,这样创建进程比fork()
还要简单。
join()
方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
Pool
如果要启动大量的子进程,可以用进程池的方式批量创建子进程:
from multiprocessing import Pool import os, time, random def long_time_task(name): print('Run task %s (%s)...' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() p.join() print('All subprocesses done.')
进程间的通信
父进程可以指定子进程执行的方法及其参数, 达到父进程向子进程传递消息的单向通信的目的, 那子进程之间或子进程怎么向父进程通信呢
Queue
Queue 是一种方式
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 | from multiprocessing import Process, Queue import os, time def write_queue(q): for name in ["Yi_Zhi_Yu", "Tony" ,"San"]: print "put name %s to queue" %(name) q.put(name) time.sleep(2) print "write data finished" def read_queue(q): print "begin to read data" while True: name = q.get() print "get name %s from queue" %(name) if __name__ == "__main__": q = Queue() pw = Process(target=write_queue, args=(q,)) pr = Process(target=read_queue,args=(q,)) pw.start() pr.start() pw.join() #这个表示是否阻塞方式启动进程, 如果要立即读取的话, 两个进程的启动就应该是非阻塞式的, 所以pw在start后不能立即使用pw.join(), 要等pr start后方可 pr.terminate() #服务进程,强制停止 |
进程交互
典型的场景就是,父进程内开启一个子进程,并获取子进程的执行的返回结果。
这个时候,就需要指定stdin, stdout为PIPE形式了。否则的话,两个进程之间是无法进行交流的。这就好比两个池塘,相互有自己的资源,如果内有一个通道的话,两个池塘就没办法”交流“。
1.py
import sys
s = "this is from {}".format(__file__)
sys.stdout.write(s)
- 1
- 2
- 3
- 4
- 5
2.py
import subprocess
import sys
try:
child = subprocess.Popen('python ./1.py', stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)
print child.stdout.readline()
except Exception as e:
print e