多进程
windows和unix/linux系统的区别:
unix/linux系统提供了一个fork()系统调用,普通函数调用一次返回一次,而fork()调用一次返回两次。
而windows系统上没有fork()调用
第一种方法创建子进程:linux/unix独有
linux/unix系统使用fork()函数创建子进程,模式如下:
#!/usr/bin/env python
import os
print "process %s start....." % (os.getpid())
pid=os.fork() pid有两种值,一种是0(代表子进程),另外一种是子进程ID(代表父进程)
if pid == 0: 当pid=0的时候,os.getpid()得到子进程,os.getppid()得到父进程
print "child process %s and parent process %s" % (os.getpid(),os.getppid())
else: 否则pid等于子进程ID,os.getpid()得到父进程
print "I am parent %s create %s " % (os.getpid(),pid)
第二种方法:通过一个multiprocess模块中的类Process来创建子进程。通用linux,windows ,unix
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",)) 创建一个Process类的实例,并且传入一个函数和参数
print "child process will start"
p.start() 通过start来启动
p.join() join方法可以等待子进程结束后再往下继续执行 ,用于进程间同步
print "child process end"
第三中方法:用进程池批量创建子进程
方法一:我们通过Pool类创建出25各进程,然后再创建100各任务,然后每个进程执行4个任务,并把执行后的结果放在一个列表中,最后我们通过.get遍历这个列表把结果取出来
#!/usr/bin/env python
import multiprocessing
import sys,os,time
print "Parent process:%s" % (os.getpid())
result=[]
def run(h):
print "threading test:",h,os.getpid()
time.sleep(2)
p=multiprocessing.Pool(processes=25) 一次创建25各进程。
for i in range(100):
result.append(p.apply_async(run,('%s'%i,))) 执行run函数100次,并把执行的结果放在一个列表中,相当于每个进行执行函数4次
p.close()
p.join()
for res in result:
res.get(timeout=5) 通过.get获取列表中的元素
方法二:不需要通过列表,也可得出执行后的结果
#!/usr/bin/env python
#! -*- encoding:utf-8 -*-
from multiprocessing import Pool
import os,time,random
def long_time_task(name):
print "run tas %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(5)
for i in xrange(5):
p.apply_async(long_time_task,args=(i,))
print "waiting for all subprocess done "
p.close() join方法可以等待子进程结束后再往下继续执行,在join之前要先close,close之后不会添加新的process
p.join()
注意:如果我们有5各cpu,然后我们创建5个进程,执行5个任务的话,那么平均每个进程会占用一个cpu,并且执行一个任务,这时5各任务会同时执行,看不到等待效果。
------进程间的通信机制:通过Queue,Pipes来交换数据---------
'''
from multiprocessing import Process,Queue
import os,time,random
def write(q): #定义一个写函数
print("Process to write: %s" % os.getpid())
for value in ["a","b","c","d"]:
print "put %s to queue.." % value
q.put(value)
time.sleep(random.random())
def read(q): #定义一个读函数
print "process %s to read" % os.getpid()
while True:
value = q.get(True)
print "get %s from queue" % value
if __name__ == "__main__":
q=Queue() #创建Queue对象
pw=Process(target=write,args=(q,)) #创建一个写进程
pr=Process(target=read,args=(q,)) #创建一个读进程
pw.start() #开启读进程
pr.start() #开启写进程
pw.join() #等待写进程结束
pr.terminate() #由于读进程用的是死循环,无法等待其结束,只有强制结束

浙公网安备 33010602011771号