本文以一个简单的例子介绍python中多线程和多进程的差别。
我们在进行生信分析时经常要处理大文件,如果用串行运算往往费时,所以需要并行运算以节省时间。目前,流行的生信工具通常都可以并行运算,比如bwa。通常来讲,我们进行并行运算可以选择多线程或者多进程。那么二者有什么差别呢,我们又该如何选择呢?
不同编程语言中的多线程和多进程实现机制是不一样的,其实我们不关心实现机制,我们关注的是实际的性能。本文以python语言为例,用一个测试脚本来比较python中多线程和多进程的性能区别。我们主要关注运行时间和内存占用情况。
我们知道,python中常用的多线程模块是threading,常用的多进程模块是multiprocessing。我们的测试脚本要解决的是一个运算量比较大的任务,根据是否(并行)运算以及使用哪种并行运算可以分为四种情形:
得到的结果如下:
从中可以看出,对这个运算任务以及测试脚本而言,与串行运算相比,多线程所用的时间多很多,所占的内存一样;而多进程所用的时间变少(大约是串行运算时间的一半),所占用的内存变大(大约是串行运算的三倍)。
上述结果值得讨论的有两个:
综上,由于生信分析大多是CPU密集型(计算密集型)的任务,如果你用python来处理此类任务,多进程并行运算可能更适合。
参考
[1] https://www.cnblogs.com/yssjun/p/11302500.html
所用的测试脚本如下:
#!/usr/bin/python
from threading import Thread
from multiprocessing import Process
import time
import sys
def test_func(n):
for _ in range(n):
for i in a:
j = i + 1
print j
a = [1] * 10000000 # 10M
ncore = 2
per_run = 20
total_run = ncore * per_run
if __name__ == "__main__":
start_time = time.time()
if len(sys.argv) < 2:
print "Usage: python %s <no-calc | serial | multi-thread | multi-process>" % sys.argv[0]
sys.exit(1)
cores = None
if sys.argv[1] == "no-calc":
time.sleep(1)
elif sys.argv[1] == "serial":
test_func(total_run)
elif sys.argv[1] == "multi-thread":
cores = [Thread(target = test_func, args=(per_run, )) for _ in range(ncore)]
elif sys.argv[1] == "multi-process":
cores = [Process(target = test_func, args=(per_run, )) for _ in range(ncore)]
else:
print "Usage: python %s <no-calc | serial | multi-thread | multi-process>" % sys.argv[0]
sys.exit(3)
if cores:
for cr in cores:
cr.start()
for cr in cores:
cr.join()
end_time = time.time()
print end_time - start_time