小言_互联网的博客

python多进程,python multiprocessing 多进程使用方法

289人阅读  评论(0)

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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场