【发布时间】:2013-06-29 18:15:10
【问题描述】:
基于这个question,我假设创建新进程应该几乎与在Linux中创建新线程一样快。然而,很少的测试显示出非常不同的结果。这是我的代码:
from multiprocessing import Process, Pool
from threading import Thread
times = 1000
def inc(a):
b = 1
return a + b
def processes():
for i in xrange(times):
p = Process(target=inc, args=(i, ))
p.start()
p.join()
def threads():
for i in xrange(times):
t = Thread(target=inc, args=(i, ))
t.start()
t.join()
测试:
>>> timeit processes()
1 loops, best of 3: 3.8 s per loop
>>> timeit threads()
10 loops, best of 3: 98.6 ms per loop
因此,创建过程几乎要慢 40 倍!为什么会这样?它是特定于 Python 还是这些库?还是我只是误解了上面的答案?
UPD 1. 使其更清晰。我知道这段代码实际上并没有引入任何并发性。这里的目标是测试创建进程和线程所需的时间。要在 Python 中使用真正的并发,可以使用如下方式:
def pools():
pool = Pool(10)
pool.map(inc, xrange(times))
它的运行速度确实比线程版本快得多。
UPD 2.我添加了带有os.fork()的版本:
for i in xrange(times):
child_pid = os.fork()
if child_pid:
os.waitpid(child_pid, 0)
else:
exit(-1)
结果是:
$ time python test_fork.py
real 0m3.919s
user 0m0.040s
sys 0m0.208s
$ time python test_multiprocessing.py
real 0m1.088s
user 0m0.128s
sys 0m0.292s
$ time python test_threadings.py
real 0m0.134s
user 0m0.112s
sys 0m0.048s
【问题讨论】:
-
嗯,您链接到的问题是比较仅调用
fork(2)与pthread_create(3)的成本,而您的代码做得更多。比较os.fork()和thread.start_new_thread()怎么样? -
@Aya: 我在
thread模块中找不到任何类型的join来创建类似的测试,但即使与带有os.fork()的高级threading版本相比仍然很多慢点。事实上,它是最慢的(尽管附加条件可能会影响性能)。查看我的更新。 -
如果你使用低级
thread模块,你必须使用互斥锁来等待线程,这就是高级threading模块实现join()的方式。但是,如果您只是想测量创建新进程/线程所需的时间,那么您不应该调用join()。另请参阅下面的答案。
标签: python linux multithreading multiprocessing