python中多线程,由于GIL锁的存在,即使在多核的情况下,多线程也无法实现真正的并行,而只是并发。因此python中经常需要使用多进程。对于多进程python由multiprocessing提供了相应的API,该模块封装了对于多进程的操作。在实际的使用过程中,引用该模块,则可以实现多核情况下多线程并行执行一个任务。
python3中通常自带multiprocessing模块,因此不需要额外的安装。
如下以并行的解析一个目录下的证书文件为例,说明multiprocessing的使用方法:
import sys
import os
import time
import multiprocessing
from OpenSSL import crypto
#遍历文件目录
def getAllFileName(filePath,allFileName):
#for filename in os.listdir(filePath):
#allFileName.append(filename)
#print(filename)
for root,dirs,files in os.walk(filePath):
allFileName[root] = files
#for f in files:
#allFileName.append(os.path.join(root,f))
#print(os.path.join(root,f).split('/')[-1])
#解析ssl证书,获取证书subject中的信息
def getCertSubjectInfo(certName):
certSubjectInfo = []
try:
cert = crypto.load_certificate(crypto.FILETYPE_ASN1, open(certName,'rb').read())
subject = cert.get_subject()
certSubjectInfo.append(subject.O)
certSubjectInfo.append(subject.C)
certSubjectInfo.append(subject.L)
certSubjectInfo.append(subject.ST)
certSubjectInfo.append(subject.CN)
certSubjectInfo.append(subject.OU)
except Exception as e:
print(certName,e)
return certSubjectInfo
#多进程任务
def certTask(rootPath,aCertFileName,rowInfo,lock):
aCertSubjectInfo = getCertSubjectInfo(rootPath+ str(os.path.sep) +aCertFileName)
with lock:
if (len(rowInfo) % 10000 == 0):
print(len(rowInfo))
if(6 == len(aCertSubjectInfo)):
rowInfo.append(aCertSubjectInfo)
#将多进程管理封装成该函数
def manageMultiProcess(task,rootPath,allFileName):
manager = multiprocessing.Manager()
rowInfo = manager.list()
lock = manager.Lock()
pool = multiprocessing.Pool(processes = 50)#进程池,最多分配50个进程
startTime = time.time()
for aFileName in allFileName:
pool.apply_async(task, args=(rootPath,aFileName,rowInfo,lock,))
pool.close()
pool.join()
endTime = time.time()
print("多进程执行耗时:{0:.2f}".format(endTime - startTime))
return rowInfo
if __name__ == '__main__':
certFilePath = '/data/certFile'
allCertFileName = {}
getAllFileName(certFilePath,allCertFileName)
for rootPath,allFileNameOfAFolder in allCertFileName.items():
data = manageMultiProcess(certTask ,rootPath,allFileNameOfAFolder)
1,getAllFileName
遍历文件目录函数,由于filePath下可能会存在其他的目录,因此根据绝对路径的不同,将当前目录下的文件(列表形式)存入字典allFileName中。Key即路径名称,value即该路径下的文件列表。
2,getCertSubjectInfo
获取证书函数,调用OpenSSL中的crypto模块解析证书文件,例如.cer文件。
3,certTask
为多进程执行的任务函数,通过调用getCertSubjectInfo
,该函数即获取证书信息,以列表形式返回。可以根据要执行的任务的不同,自行修改此处的任务函数。
4,manageMultiProcess
即进程管理需要的一些操作,包括进程池的申请,关闭,以及在访问共享资源时候,加入锁等。apply_async
函数中task即任务函数,args为传入task函数的参数列表,对应certTask函数中的形参。其中lock要注意的是要使用lock = manager.Lock()
生成,用于不同进程访问共享变量时候的互斥。
上述就是multiprocessing的简单使用方法。
本文为CSDN村中少年原创文章,转载记得加上原创出处,博主链接这里。
转载:https://blog.csdn.net/javajiawei/article/details/100939417