测试开发实践

Python组合类的多进程异步实现

2017-07-18  本文已影响135人  严北

模块和类


多进程模块

multiprocessing

多进程类

multiprocessing.Process
multiprocessing.Pool

用户类

A、B、C
其中B、C类组合为A,(原设想为B、C继承A,考虑到B、C的功能需要多线程/进程同时运行,因此采用组合类的方式)

用户类的组合


class A(object):
    def __init__(self, user):
        self.user = user
        self.b = B("B", self.user)
        self.c = C("C", self.user)

class B(object):
    def __init__(self, things, user):
        self.user = user
    def print(self):
        print self.user

class C(object):
    def __init__(self, things, user):
        self.user = user
    def print(self):
        print self.user

B类继承多进程类


class B(multiprocessing.Process):
    def __init__(self, things, user):
        multiprocessing.Process.__init__(self)
        self.user = user
    def print(self):
        print self.user
    def run(self):
        self.print()

运行进程

a = A("me")
a.b.start()

若需要单独传B的参数,而非在A类中限定死,那么改变A类中对B的组合形式,将B类从成员改为方法

class A(object):
    def __init__(self, user):
        self.user = user
    def Do_B(self, things):
        return B(things, self.user)
    def Do_C(self, things):
        return C(things, self.user)

此时运行进程方式变为

a = A("me")
a.Do_B("hello").start()

B的整个过程包括:

  1. 创建对象并初始化(执行init方法);
  2. 收到start请求后执行run方法。

虽然对单一线程来说,将run方法中的执行语句放在init方法中也会有一样的结果,但当你尝试异步执行该线程时会发现,即使你用了异步方法,结果确实同步执行。原因就在于继承Process类的子类在初始化对象时需要执行init方法,因此不能偷懒在初始化时执行过多方法,只做一些赋初值操作是一个很好的选择。

使用Pool类


创建进程池

pool = multiprocessing.Pool()

可以指定并发进程数,默认为cpu内核数

# 指定并发数为2
pool = multiprocessing.Pool(2)
# 指定并发数为cpu内核数-1
pool = multiprocessing.Pool(multiprocessing.cpu_count()-1)

异步运行进程

a = A("me")
# 创建B类对象
aa = a.Do_B("aa")
bb = a.Do_B("bb")
cc = a.Do_B("cc")
dd = a.Do_B("dd")
ee = a.Do_B("ee")
list = [aa, bb, cc, dd, ee]
for i in range(5)
# 将对象添加到进程池,并用异步方法启动
    pool.apply_async(list[i])
# 停止新的进程加入进程池
pool.close()
# 阻塞主进程
pool.join()
上一篇下一篇

猜你喜欢

热点阅读