gevent和multiprocess的区别

时间:2016-10-01 10:59:06

标签: python python-2.7 parallel-processing multiprocessing gevent

我正在学习如何让我的脚本运行得更快。我认为平行是一种好方法。所以我尝试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. 为什么在前1,f_para可以更改全局数组a的值?

  2. 为什么在前2,f2_asy不能并行?

  3. 任何人都知道gevent和多处理之间的区别?如果你愿意解释,我将非常感激。

1 个答案:

答案 0 :(得分:1)

EX1:

当您使用多进程时,每个进程都有单独的内存(与线程不同)

EX2:

gevent不会创建线程,它会创建Greenlets(协同程序)!

  

Greenlets全部在主程序的OS进程内部运行,但是是合作安排的。

     

在任何给定时间只运行一个greenlet。

     

这与多处理或线程库提供的任何真正的并行结构不同,后者执行旋转过程和POSIX线程,这些线程由操作系统调度并且是真正并行的。