2012-06-25 79 views
3

我一直在使用this link瞭解多,但我卡在第二個例子:multiprocessing.Process .__ init __(self)做什麼?

import multiprocessing 
import time 

class Consumer(multiprocessing.Process): 

    def __init__(self, task_queue, result_queue): 
     multiprocessing.Process.__init__(self) 
     self.task_queue = task_queue 
     self.result_queue = result_queue 

    def run(self): 
     proc_name = self.name 
     while True: 
      next_task = self.task_queue.get() 
      if next_task is None: 
       # Poison pill means we should exit 
       print '%s: Exiting' % proc_name 
       break 
      print '%s: %s' % (proc_name, next_task) 
      answer = next_task() 
      self.result_queue.put(answer) 
     return 


class Task(object): 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 
    def __call__(self): 
     time.sleep(0.1) # pretend to take some time to do our work 
     return '%s * %s = %s' % (self.a, self.b, self.a * self.b) 
    def __str__(self): 
     return '%s * %s' % (self.a, self.b) 


if __name__ == '__main__': 
    # Establish communication queues 
    tasks = multiprocessing.Queue() 
    results = multiprocessing.Queue() 

    # Start consumers 
    num_consumers = multiprocessing.cpu_count() * 2 
    print 'Creating %d consumers' % num_consumers 
    consumers = [ Consumer(tasks, results) 
        for i in xrange(num_consumers) ] 
    for w in consumers: 
     w.start() 

    # Enqueue jobs 
    num_jobs = 10 
    for i in xrange(num_jobs): 
     tasks.put(Task(i, i)) 

    # Add a poison pill for each consumer 
    for i in xrange(num_consumers): 
     tasks.put(None) 

    # Start printing results 
    while num_jobs: 
     result = results.get() 
     print 'Result:', result 
     num_jobs -= 1 

首先,可能有人請解釋什麼multiprocessing.Process.__init__(self)呢?我也不完全確定隊列是如何工作的,我很困惑如何執行Consumer類中的run方法,即使它從未被調用過(明確地說至少是...)

如果有人能幫助我通過示例來獲得給定的輸出,將不勝感激。

+0

也許[這個問題](http://stackoverflow.com/questions/625083/python-init-and-self-what-do-they-do)可以幫助你。我幾乎提出它是你的副本。 – brandizzi

+0

@brandizzi這個問題是關於Python的'self'和'__init__'的基本問題。這裏的OP的問題是關於爲什麼'__init__'正在調用'multiprocessing.Process .__ init __(self)'(它基本上稱它是父級的init) –

回答

1

當一個類的對象被創建時,它的__init__()方法被自動調用來初始化它。在第二個例子中,類Consumer被定義爲從multiprocess.Process繼承。 Consumer在初始化時的第一件事情是初始化其基地Process,以確保它已準備好運行。與許多OO語言不同,基類__init__()函數不會在Python中自動調用。

當在主進程中的Consumer對象上調用start()時,將在新進程中自動調用run()方法。這在multiprocessing文檔中。

Queue是多個進程如何通信。通常,單獨的進程不能看到彼此的數據,但Queue可讓它們來回傳遞消息。在這個例子中,主進程將幾個任務放入一個隊列中,其他每個進程都將從該隊列中取出一個任務,執行該任務,並將結果發送回另一個隊列。

+0

謝謝,我沒有意識到__init __()不會自動調用Process。如果消費者有更多的方法,它們是否會被自動調用? – aensm

+0

不,'run()'很特別 - 閱讀文檔。你可以從'run()'中明確地調用消費者的其他方法,但是它們不會被自動調用。 –

0

__init__是一個類的構造函數。有一些更多的背景請看here

根據the docs這必須調用子類:

如果子類重寫的構造函數,它必須確保它在做任何事情之前調用基類構造函數(過程INIT())。到這個過程。

0

嗯,這可能不是你正在尋找的答案...但我認爲是最好的答案。

Process對象在創建時應該做很多艱難的事情。我不知道它應該做什麼,但我確信它應該創建另一個操作系統進程,用於通信的管道等。默認情況下,所有這些東西都在初始化方法中執行(在Python中,稱爲__init__())。因此,如果您創建Process的子級,則應該調用父級__init__()方法來初始化進程所需的所有內容。由於您的Consumer課程應該完成Process所做的所有工作,它應該具有Process所具有的所有內容,並且__init__()調用可以確保它。

什麼究竟是它確實是無關緊要的。這就是現有方法的全部要點,如__init__():他們爲您執行艱苦的工作,您只需要調用它。所以,we could get deep into the Python source code to see what __init__() does,但是對於你來說,現在似乎是以Python開始的,最好的答案是__init__()做了許多你不需要知道的初始化工作。

相關問題