不能使用Pool.map()来pickle实例方法,但我没有实例方法

时间:2013-06-13 17:21:22

标签: python multiprocessing pickle pool

我正在尝试使用multiprocessing.Pool对象并行运行一些数据库查询。我正在使用MySQLdb。

我有一些模块级函数,我定义要运行的查询,如下所示:

def check_foo(cursor, table):
    query = "(some query)"
    cursor.execute(query)
    results = cursor.fetchall()
    return len(results) == 0

运行程序时会收集这些函数,如下所示:

if __name__ == '__main__':
    check_functions = [v for k, v in globals().items()
                             if k.startswith('check_') and callable(v)]

我还有一个模块级函数,它在表列表上运行特定的检查函数:

def run_check_on_all((tables, cursor, f)):
    return [f(cursor, table) for table in tables]

我想为每个检查函数设置一个工作进程,该函数将为该函数调用run_check_on_all。这是我尝试这样做的:

if __name__ == '__main__':
    ...

    pool = multiprocessing.Pool(len(check_functions))
    cursors = [conn.cursor() for i in range(len(check_functions))]

    print "Running {0} check(s)...".format(len(check_functions))
    table_lists = [table_list] * len(check_functions)
    all_results = pool.map(run_check_on_all, zip(table_lists, cursors, check_functions))

当我尝试运行此操作时,出现以下错误:

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

正如您所希望的那样,pool.map调用中涉及的任何内容都不是实例方法。 run_check_on_all和每个check_functions都是模块级函数。 table_lists是字符串列表的列表。 cursors是MySQLdb游标对象的列表。

我想也许它可能与在check函数中调用游标对象的实例方法有关,但是我用这样的虚函数替换了它们

def check_foo(cursor, table):
    print "hello"

但仍然没有运气。

错误所指的实例方法在哪里?

1 个答案:

答案 0 :(得分:1)

问题是您尝试在进程之间传递数据库游标对象。每个进程都必须创建与数据库的连接,并在该连接上创建游标。