2013-06-21 10 views
12

でマルチプロセッシング管理:キューを充填し、私はpythonでこの問題を抱えているのpython

  • 私はキューがいっぱいになる場合は、随時
  • にチェックする必要があるURLのキューを持っています、私はこれまでのところ、私はこのように、この「手動」を達成するために管理し、キュー内の各項目は、単一のプロセス(マルチプロセッシング)

によって処理されなければならない

  • キュー内の各項目を処理する必要があります。

    while 1: 
         self.updateQueue() 
    
         while not self.mainUrlQueue.empty(): 
          domain = self.mainUrlQueue.get() 
    
          # if we didn't launched any process yet, we need to do so 
          if len(self.jobs) < maxprocess: 
           self.startJob(domain) 
           #time.sleep(1) 
          else: 
           # If we already have process started we need to clear the old process in our pool and start new ones 
           jobdone = 0 
    
           # We circle through each of the process, until we find one free ; only then leave the loop 
           while jobdone == 0: 
            for p in self.jobs : 
             #print "entering loop" 
             # if the process finished 
             if not p.is_alive() and jobdone == 0: 
              #print str(p.pid) + " job dead, starting new one" 
              self.jobs.remove(p) 
              self.startJob(domain) 
              jobdone = 1 
    

    しかし、それは問題とエラーのトンにつながります。私は、プロセスのプールを使用して私がより良く適合していないかどうか疑問に思いました。これを行う正しい方法は何でしょうか?

    しかし、私のキューは何度も空であり、1秒間に300個のアイテムで塗りつぶすことができるので、ここでどのように行うかについてはあまりよく分かりません。

  • 答えて

    20

    queueのブロッキング機能を使用して、起動時に(multiprocessing.Poolを使用して)複数のプロセスを起動し、キューに処理可能なデータがあるまでスリープさせることができます。それを使用して慣れていない場合は、その簡単なプログラムで「遊ぶ」しようとすることができます。Linux上でのPython 2.7.3でテスト

    import multiprocessing 
    import os 
    import time 
    
    the_queue = multiprocessing.Queue() 
    
    
    def worker_main(queue): 
        print os.getpid(),"working" 
        while True: 
         item = queue.get(True) 
         print os.getpid(), "got", item 
         time.sleep(1) # simulate a "long" operation 
    
    the_pool = multiprocessing.Pool(3, worker_main,(the_queue,)) 
    #       don't forget the coma here^
    
    for i in range(5): 
        the_queue.put("hello") 
        the_queue.put("world") 
    
    
    time.sleep(10) 
    

    これは、のほかに(3つのプロセスを生成します親プロセス)。各子はworker_main関数を実行します。各繰り返しでキューから新しい項目を取得する単純なループです。労働者は何も処理する準備ができていなければ、ブロックします。

    起動時に、3つのプロセスすべてがキューにデータが入力されるまでスリープします。データが利用可能になると、待機中の労働者のうちの1人がそのアイテムを取得し、それを処理し始める。その後、他のアイテムを待ち行列から取得しようとします。何も利用できない場合は、再び待機します。

    +0

    これはPython 2.7.4のウィンドウでは機能しません。if __name__ = '__main__' 3番目のパラメータとしてthe_queueをmultiprocessing.Pool関数に渡す必要があります。そうでなければ、worker_mainはデータを受け取りません。 – jhexp

    +0

    このコードを動作させる方法にも興味があります。私はそれを実行すると、それは実行されますが、おそらくworker_mainがデータを受け取らないため、何も印刷しません。しかし、私がthe_queueを3番目のパラメータとして渡すと、TypeErrorが返されます。* worker_main()の後の引数*はシーケンスでなければなりません。 – ziky90

    +0

    @ ziky90おそらく '(queue、)'に昏睡を忘れました。コードを編集して、可能なエラーの原因を指摘するコメントを追加しました。 –

    関連する問題