4

我正在學習如何讓腳本運行得更快。我認爲平行是一個好方法。所以我嘗試了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. 爲什麼在EX 1,f_para可以改變全局數組a的價值?

  2. 爲什麼在ex 2中,f2_asy不能做平行嗎?

劑量任何知道gevent和multiprocessing之間的區別?如果你願意解釋它,我非常感激。

回答

1

EX1:

當您使用多進程每個進程都有獨立的內存(不像線程)

EX2:

GEVENT不創建線程,它創建Greenlets(協程)!

Greenlets全部在主程序的OS進程內部運行,但是被合作調度。

在任何給定的時間只有一個greenlet在運行。

這不同於多處理或線程庫提供的真正的並行性結構,它們執行由操作系統調度並且真正並行的旋轉進程和POSIX線程。

+0

謝謝,但我仍然困惑。對於ex1,我打印id(a),id是一樣的。所以我不明白爲什麼一個[i]的變化不會富裕一個。對於ex2,我的困惑是gevent應該在我的計算機中產生8個Greenlet和每個Greenlet運行函數f2。 Greenlet運行函數f1或f2應該沒有區別。 – insomnia

相關問題