Python multiprocessing 线程池的一点体会

问题背景:

多线程、多进程是常用的提高程序执行效率的方法。python中multiprocessing 包支持多进程。

下边是一个简单的多进程demo:

from multiprocessing import Pool


def f(x):  # 基本函数返回 x的平方
    return x * x


def my_callback(x):  # 回调函数,打印x
    print(x)


def multicore():
    pool = Pool(4)  # 创建可容纳四个进程的进程池
    for i in range(10):  # 从进程池中取出进程执行基本函数f,然后调用回调函数打印结果,执行10次
        pool.apply_async(f, args=(i,), callback=my_callback)
    pool.close()  # 关闭进程池, 不允许再添加新的进程
    pool.join()  # 等待所有子进程执行完毕


print("test")
if __name__ == '__main__':  # 主进程时执行
    multicore()

对于这个demo, 我们期望的执行情况是这样的: 先打印出 "test", 然后创建容纳4个进程的进程池, 通过进程池调用进程完成10次循环. 然而实际的执行结果却是这样的(用","替换了换行):

test,test,test,0,1,4,9,16,25,36,49,64,81,test,test

这里print("test")执行了5 次 显然不是我们期望的结果,为什么会这样呢?

分析:

为了便于我们分析,现修改部分代码如下:

print("test")
print("%d-------- main out" % os.getpid())
if __name__ == '__main__':  # 主进程时执行
    print("%d-------- main in" % os.getpid())
    multicore()

 引入包 os,两处打印进程号,一次在"__main__"模块外, 一次在"__main__"模块内.结果如下:

test
4072-------- main out
4072-------- main in
test
8248-------- main out
test
11932-------- main out
0
1
4
9
16
25
36
49
64
81
test
4892-------- main out
test
4060-------- main out

从上述结果中我们可以看到,"__main__"模块内的getpid()执行了一次, 该模块外的getpid()执行了5次, 其中有一次pid值与"__main__"内的getpid()相同.

由进程的基本概念,我们知道进程分为主(父)进程、子进程。当我们执行 test.py时,执行的进程为主进程, 这时打印出第一个test, getpid()--main out, 因为主进程的__name__值为 "__main__", 因此执行 "__main__"模块, 打印出 getpid()-- main in, 开始调用multicore()方法.

这时线程创建了可容纳四个进程的进程池, 进程池开始一个一个添加进程, 每当添加一个新的进程时, 该进程便会扫描整个py文件,当扫描到

print("test")
print("%d-------- main out" % os.getpid())

便会执行,因此可以看到另外4个 test, 和 pid --- main out.

至此整个分析基本结束, 你也许会问, 子进程扫描的时候, 也扫描到了 

if __name__ == '__main__':  # 主进程时执行
    print("%d-------- main in" % os.getpid())
    multicore()

为什么不执行呢? 

这是因为子进程的 "__name__"值 不等于 "__main__", 可以打印一下试试

print(__name__)

结语:

好了, 整个分析过程就是这样. 简单的说 进程池会创建一批子进程, 这些子进程会把该py文件所有可执行的语句都执行了, 因此不想让子进程执行的语句要放在函数体内, 或者放在

if __name__ == '__main__':  # 主进程时执行

语句下边.

参考文献:

如何简单地理解Python中的if __name__ == '__main__'

 

你可能感兴趣的:(Python,Python,多进程,multiprocessing,进程池)