5

Pythonマルチプロセスパッケージのpool.mapを使用して、データベース接続オブジェクトまたはカーソルオブジェクトを渡すのに問題があります。基本的に、それぞれが独自の状態とデータベース接続を持つワーカーのプールを作成して、クエリを並行して実行できるようにします。

私はこれらのアプローチを試しましたが、Pythonでピクリングエラーが発生しています-

2つのarugementsを含むプールマップ

イニシャライザを使用してマルチプロセスプールを設定する

2番目のリンクはまさに​​私が行う必要があることです。つまり、各プロセスが開始時にデータベース接続を開き、その接続を使用して渡されたデータ/引数を処理する必要があります。

これが私のコードです。

import multiprocessing as mp

def process_data((id,db)):
  print 'in processdata'
  cursor = db.cursor()
  query = ....
  #cursor.execute(query)
  #....
  .....
  .....
  return row

`if __name__ == '__main__':

  db = getConnection() 
  cursor = db.cursor() 
  print 'Initialised db connection and cursor'
  inputs = [1,2,3,4,5]
  pool = mp.Pool(processes=2)
  result_list = pool.map(process_data,zip(inputs,repeat(db)))
  #print result_list
  pool.close()
  pool.join() 

`

これにより、次のエラーが発生します-

`Exception in thread Thread-1:
  Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.6/multiprocessing/pool.py", line 225, in _handle_tasks
    put(task)
  PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed`

pythonによれば、dbまたはcursorオブジェクトは選択できないと思います。repeat(db)をrepeat(x)に置き換えると、xはintまたはstringであり、機能するからです。イニシャライザ関数を使用してみましたが、最初は機能しているようですが、クエリを実行すると奇妙なことが起こり、データが存在する場合、多くの場合IDに対して何も返されません。

これを達成するための最良の方法は何でしょうか?LinuxマシンでPython2.6.6を使用しています。

4

2 に答える 2

10

一つとして適切だと思うので、先に進んでコメントを答えとしてあげます。親プロセスから子プロセスにデータベース接続を渡そうとしないでください。子プロセスにシリアル化できる静的データまたはその他のオブジェクトを移動する必要があります。データの行などを渡すことができます。または、必要になったときに子供に独自のデータベース接続を確立させたい場合もあります。

于 2012-09-27T05:59:16.840 に答える
-2

db接続オブジェクトをピクルスにしてみてください。酸洗いはプロセスに依存しません。だからそれはうまくいくかもしれません。

これらのページを参照してください-pythonpicklepickleの

于 2012-09-27T07:35:38.500 に答える