多处理 - 返回不可拾取的对象?

Multiprocessing - returning unpickleable objects?

我实际上已经问过 a question about multiprocessing before,但现在我 运行发现返回的数据类型有一个奇怪的缺点。

我正在使用 Gspread 与 Google 的 Sheets API 交互并获取 "worksheet" 对象。

由于 "unpickle-able",此对象或此对象的一个​​方面显然与多处理不兼容。请查看输出:

File "/usr/lib64/python2.7/multiprocessing/pool.py", line 554, in get
raise self._value

multiprocessing.pool.MaybeEncodingError: Error sending result: '[<Worksheet 'Activation Log' id:o12345wm>]'. 
Reason: 'UnpickleableError(<ssl.SSLContext object at 0x1e4be30>,)'

我使用的代码本质上是:

from multiprocessing import pool
from oauth2client.client import SignedJwtAssertionCredentials
import gspread

sheet = 1
pool = multiprocessing.pool.Pool(1)
p = pool.apply_async(get_a_worksheet, args=(sheet,))

worksheet = p.get()

并且脚本在尝试 "get" 结果时失败。 get_a_worksheet 函数 returns 一个 Gspread worksheet 对象,它允许我操作遥控器 sheet。能够将更改上传到文档在这里很重要 - 我不只是尝试引用数据,我还需要更改它。

有谁知道我如何 运行 在单独的可监视线程中创建子进程,并在最后安全地从中获取任意(或自定义)对象类型?有谁知道 ssl.SSLContext 对象和 "unpickleable" 的特殊之处?

提前致谢。

Multiprocessing 使用 pickling 在进程之间传递对象。所以我不相信你可以使用 multiprocessing 并使一个对象不可 picklable。

我最终通过让子流程简单地在其内部执行必要的工作而不是 return 一个 Worksheet 对象来解决这个缺点。

我最终得到的是大约六个函数和多处理函数对,每个函数都是为完成我需要完成的而编写的,但都在一个子进程内部,以便可以对其进行监视和计时。

分层地图看起来像:

Main()
    check_spreadsheet_for_a_string()
        check_spreadsheet_for_a_string_worker()
    get_hash_of_spreadsheet()
        get_hash_of_spreadsheet_worker()

...等等

其中 "worker" 函数是在多处理设置中调用的函数,它们上面的常规函数​​管理子进程并对其计时以确保整个程序在调用时不会停止gspread 内部挂起或耗时太长。