2012-03-29 40 views
6

我想用並行執行來實現一個簡單的python程序。它是I/O綁定的,所以我認爲線程是合適的(與流程相反)。在閱讀Queue和fork的文檔後,我認爲類似下面的內容可能會起作用。瞭解os.fork和Queue.Queue

q = Queue.Queue() 

if os.fork():   # child 
    while True: 
     print q.get() 
else:     # parent 
    [q.put(x) for x in range(10)] 

但是,get()調用永遠不會返回。我認爲一旦其他線程執行put()調用就會返回。使用線程模塊,事情表現得更像我所料:

q = Queue.Queue() 

def consume(q): 
    while True: 
     print q.get() 

worker = threading.Thread (target=consume, args=(q,)) 
worker.start() 

[q.put(x) for x in range(10)] 

我只是不明白爲什麼fork方法不會做同樣的事情。我錯過了什麼?

回答

7

的POSIX fork系統調用創建一個新的過程,而不是一個新的線程相同的尋址空間內:

叉()函數將創建一個新的進程。 [...]

所以Queue是你的第一個例子複製的,而不是:新進程(子 過程)應除詳細如下是調用進程(父 過程)的精確副本在父母和孩子之間分享。

您可以使用multiprocessing.Queue代替或只是在你的第二個例子:)

順便說使用線程一樣,通過遍歷的只是副作用isn't good practice有幾個原因。您應該使用for循環代替:

for x in range(10): q.put(x) 
+1

提及'multiprocessing'的+1。 – 2012-03-29 21:04:16

0

叉子創建一個新過程。子進程和父進程不共享相同的隊列:這就是爲什麼父進程放置的元素不能被子進程檢索的原因。

1

要在不相關進程之間共享數據,可以使用命名管道。通過os.open()函數.. http://docs.python.org/2/library/os.html#os.open。您可以簡單地將管道命名爲named_pipe ='my_pipe',並在不同的python程序中使用os.open(named_pipe,),其中模式爲WRONLY等。之後,您將創建一個FIFO以寫入管道。不要忘了關閉管道和捕捉異常。