使用multiprocessing模块来进行python的多进程编程。个人习惯使用类来继承原始的Process类进行处理,以下是模板,供以后拷贝使用。
#!/usr/bin/env python
# -*- coding:utf8 -*-
import os, os.path
import time
from multiprocessing import Process, cpu_count
class myProcess(Process):
def __init__(self, *argus, **keywords):
# argus 和 keywords中可以包括函数名等特殊类,不仅仅是字符串,数字,序列等常见数据类型
Process.__init__(self)
self.argus = argus
self.keywords = keywords
def run(self):
# 时间统计功能最好在run内实现。该函数内实现子进程的操作。
start_time = time.time()
print ("Proc %d start: %s" % (self.proc_seq, time.ctime(start_time)))
# 以下是自己的核心代码,即你希望该进程做任务,是批量任务的模板
# 个人核心代码结束
end_time = time.time()
dur = end_time - start_time
print ("Proc %d end: %s, Total time: %.2f" % (self.proc_seq, time.ctime(end_time), dur))
if __name__ == "__main__":
import logging
import sys
logger = logging.getLogger()
formatter = logging.Formatter('[%(filename)s:%(lineno)d] - [%(asctime)s] : *%(levelname)s* | (%(funcName)s) %(message)s', '%Y-%m-%d %H:%M:%S',)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
file_handler = logging.FileHandler(os.path.splitext(os.path.abspath(__file__))[0]+".log", 'w')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.setLevel(logging.INFO)
from optparse import OptionParser
optparser = OptionParser()
optparser.add_option('-i', "--input", dest="input", action="store", default=None, help="please input the input file/foldername")
#optparser.add_option('-o', "--output", dest="output", action="store", default=None, help="please input the output folder name")
options, args = optparser.parse_args()
if len(args) != 0:
print "wrong arguments format!"
sys.exit(-1)
if options.input == None:
print "you have to give input or output folder or filenames!\nUsage: python maxmatch12r.py -i inputfolder/file -o outputfolder"
sys.exit(-1)
# 构建等于cpu核心个数的进程进行处理
core_num = cpu_count()
# 个人代码,准备好不同数目子进程的参数
argus_list = []
keywords_list = []
# 首先,创建子进程,但是不开始运行
threads = []
for iproc in xrange(len(argus_list):
cur_proc = myProcess(iproc, argus_list[iproc], keywords_list[iproc])
threads.append(cur_proc)
# 创建好所有子进程后,再开始逐个运行
for iproc in threads:
iproc.start()
# 所有子进程都运行后,在进行父进程阻断
for iproc in threads:
iproc.join()
# 所有子进程完成后,回到父进程
logger.info("Done!")
经验是以下几点:
1. 把要让子进程做的事情,都写在run函数内,父进程就只管提供数据和代码即可。
2. 父进程调用子进程的步骤是:首先,创建所有的子进程;其次,逐个调用所有的子进程,不允许有其他操作(因为会被阻塞);最后,逐个调用join函数对父进程进行阻塞,保证子进程都运行完毕后再运行父进程。