Python学习笔记之多进程

2017/11/17 Python

ython学习笔记之多进程

最近项目中需要在Python中使用并行化,通常思路就是使用多线程实现,但是经过实践,发现多线程的实现相比没有多线程更慢一些(不知道是不是我写的有问题),查资料得知Python有一个GIL锁,多线程实际上也只是在一个cpu核心上跑。

今天又来试了多进程的实现方式,果然速度快了很多。下面贴上部分代码:

Calculator.py文件

#coding:UTF-8
class Base(): 
    #外部调用的方法,也是进程池的Master
    @staticmethod
    def execute_thread(arg):
        import re
        import multiprocessing
        import correlation as corr
        
        multiprocessing.freeze_support()    # Windows 平台要加上这句,避免 RuntimeError
        clist = re.split('@', arg.strip())
        retstr = ''
        results = []
        #Pool()默认开启cpu核心数个进程——适合cpu密集型的计算,也可以加上参数,手动声明要创建的进程数
        p = multiprocessing.Pool()
        for cdata in clist:
            #调用correlation.py文件中的work方法执行具体任务,参数为cdata,返回结果给result
            result = p.apply_async(corr.work, args=(cdata,))    
            #结果保存到results中
            results.append(result)
        #阻止向进程池中继续添加任务
        p.close()
        #等待进程退出,在使用join()之前必须调用close()或者terminate()
        p.join
        retstr = ''
        i = 0
        #要在线程执行完之后遍历,
        #如果在上面的循环中直接处理计算的结果,会导致进程池以阻塞的方式运行
        for r in results:
            a = r.get()
            # print a
            retstr = retstr + a
            if i != len(results) -1:
                retstr = retstr + '@'
            i += 1
            # if i < 10:
            #     print a

        # print retstr
        return retstr

correation.py

#coding:UTF-8
import re
import sys
import numpy as np
import math

#进程池中要执行的任务,可以直接将计算过程写在里面,这里为了方便阅读,改为调用另一个计算方法
def work(cdata):
    val = re.split(';', cdata.strip())
    return str(compute_corr(val[0], val[1]))

## x表示一个数组,y表示另一个数组或特征值
def compute_corr(xstr, ystr):
    # 隐藏了计算过程
    ……
    return returnstr

效果

任务数量 多进程方式耗时(S) 没多进程方式耗时(S)
2540 0.55 1.12
10160 3.56 5.69

注意

上面的代码Python版本是2.7的,但是据说Python3的multiprocessing模块api没有太多变化,所以应该也没问题,具体没有试过。

上面的代码在Linux(Ubuntu)上运行没有问题,但是在Windows上调用时有时会报错,暂时不知道具体原因,等知道后再来补充上。

Search

    Table of Contents