2014-07-25 138 views
0

我讀過你可以用同樣的方式使用多處理和多線程。我試過用多線程來做這件事,但它不適用於多處理。Python多處理不工作

我運行下面的代碼:

import multiprocessing 
import time 


test_list = [] 


def user_input(): 
    while True: 
     number = raw_input('Please input a number: ') 
     test_list.append(number) 


def print_func(): 
    while True: 
     for t in test_list: 
      print t 

     time.sleep(5) 


if __name__ == '__main__': 
    ui = multiprocessing.Process(target=user_input) 
    p = multiprocessing.Process(target=print_func) 

    ui.start() 
    p.start() 

我收到以下錯誤對這一計劃:

Traceback (most recent call last): 
    File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap 
    self.run() 
    File "C:\Python27\lib\multiprocessing\process.py", line 114, in run 
    self._target(*self._args, **self._kwargs) 
    File "C:\Users\Victor\Dropbox\Private\multiFile\main.py", line 10, in user_input 
    number = raw_input('Please input a number: ') 
EOFError: EOF when reading a line 
+0

它是類似的,但不是*完全*的替代品,尤其是'stdin'。 – merlin2011

回答

3

我讀過,你可以用多和多線程的同樣的方式。

直到某一點,是的。但是你超越了這一點。


第一個問題是,默認情況下,子進程不會獲得stdio。在multiprocessing.Process._bootstrap()方法

os.close(sys.stdin.fileno()) 

- 這導致的問題與流程,在流程:這是Programming guidelines解釋說:

多原本無條件調用。這已更改爲:

sys.stdin.close() 
sys.stdin = open(os.devnull) 

部分的原因是,它是危險的和難以跨越這樣的多個進程共享標準輸入輸出管道。你想要做的是在父進程中分離stdin,然後明確地將原始標準輸入傳遞給你想要接管的任何一個孩子。


第二個問題是您試圖在進程之間共享全局變量test_list

正如在編程的章節,解釋爲Windows

全局變量

記住,如果一個子進程運行的代碼試圖訪問一個全局變量,則該值它認爲(如果有的話)可能與Process.start被調用時父進程中的值不同。

換句話說,每個子進程都有自己的test_list副本,彼此完全獨立。您在user_input過程中所做的更改將不會在print_func過程中可見。

最重要的是,即使使用線程,代碼也不是很安全。如果您在線程(或進程)之間共享可變對象,則需要鎖定它們。 (是的,在許多情況下,當使用內置類型時,在CPython上,GIL恰好爲您提供安全保障,但您可以確切瞭解何時可以安全地避開它,以及如何在獲得它時調試內容錯誤的,或者你可以學習如何正確地鎖定事物。)

那麼,怎麼辦你在進程之間共享狀態?那麼,在解釋它的文檔中有一整段叫做Sharing state between processes。但它通常不容易或有趣。這就是爲什麼該部分始於:

如上所述,在進行併發編程時,通常儘可能避免使用共享狀態。使用多個進程時尤其如此。

更好的解決方案是傳遞消息而不是共享狀態。這是對Exchanging objects between processes中的幾個部分的描述,對於大多數使用情況來說這是一個更簡單的方法。

+0

那麼有什麼辦法可以使這個工作與多處理? – VictorVH

+1

@VictorVH:是的。我解釋瞭如何做到這一點:分離'stdin'並將其傳遞給子進程,並用隊列或管道上的消息代替共享全局進程。如果有一部分你不明白,甚至在閱讀鏈接的文檔後,我會很樂意解釋。 – abarnert

+0

非常感謝 – VictorVH