python – gevent和multiprocess的区别

我正在学习如何让我的脚本运行得更快.我认为平行是一种好方法.所以我尝试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.]

我发现使用多处理,全局对象永远不会改变脂肪,并且在运行f_para()之后,a仍然是原始数组.在运行f_asy()时,它是不同的,一个改变了.

前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可以改变全局数组的值?
>为什么在前2,f2_asy不能做并行?

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

最佳答案 EX1:

当你使用多进程时,每个进程都有独立的内存(不像线程)

EX2:

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

Greenlets all run inside of the OS process for the main program but are scheduled cooperatively.

Only one greenlet is ever running at any given time.

This differs from any of the real parallelism constructs provided by multiprocessing or threading libraries which do spin processes and POSIX threads which are scheduled by the operating system and are truly parallel.

点赞