我正在学习如何让我的脚本运行得更快。我认为平行是一种好方法。所以我尝试gevent和多处理。但我感到困惑的是它的结果不同。让我展示一下我遇到的两个例子,
前1:
a=np.zeros([3])
def f(i):
a[i]=1
print a
def f_para():
p=multiprocessing.Pool()
p.map(f, range(3))
def f_asy():
threads = [gevent.spawn(f, i) for i in xrange(3)]
gevent.joinall(threads)
f_para()
[ 0. 1. 0.]
[ 0. 0. 1.]
[ 1. 0. 0.]
f_asy()
[ 1. 0. 0.]
[ 1. 1. 0.]
[ 1. 1. 1.]
我发现使用多处理时,全局对象a
永远不会改变胖,并且在运行f_para()
之后,a
仍然是原始数组。在运行f_asy()
时,它会有所不同,a
已更改。
前2:
def f2(i):
subprocess.call(['./a.out', str(i)])
time.sleep(0.2)
def f2_loop():
for i in xrange(20):
f2(i)
def f2_para():
p=multiprocessing.Pool()
p.map(f2, range(20))
def f2_asy():
threads = [gevent.spawn(f2, i) for i in xrange(20)]
gevent.joinall(threads)
%timeit -n1 f2_loop()
1 loop, best of 3: 4.22 s per loop
%timeit -n1 f2_asy()
1 loop, best of 3: 4.22 s per loop
%timeit -n1 f2_para()
1 loop, best of 3: 657 ms per loop
我发现f2_asy()
不会减少运行时间。 f2_asy()
的输出是逐个的,就像f2_loop()
一样,所以我认为f2_asy()
中没有并行。
a.out
是一个简单的c ++代码:
#include <iostream>
int main(int argc, char* argv[])
{
std::cout<<argv[1]<<std::endl;
return 0;
}
所以我的问题是:
为什么在前1,f_para
可以更改全局数组a
的值?
为什么在前2,f2_asy
不能并行?
任何人都知道gevent和多处理之间的区别?如果你愿意解释,我将非常感激。
答案 0 :(得分:1)
EX1:
当您使用多进程时,每个进程都有单独的内存(与线程不同)
EX2:
gevent不会创建线程,它会创建Greenlets(协同程序)!
Greenlets全部在主程序的OS进程内部运行,但是是合作安排的。
在任何给定时间只运行一个greenlet。
这与多处理或线程库提供的任何真正的并行结构不同,后者执行旋转过程和POSIX线程,这些线程由操作系统调度并且是真正并行的。