簡體   English   中英

不能多進程用戶定義的代碼-無法腌制

[英]can't multiprocess user defined code - cannot pickle

我嘗試對任務使用多處理,這通常意味着先進行一些計算然后將結果傳回。 問題是定義計算的代碼是由用戶定義的,它是在執行之前從字符串編譯的。 在主進程中運行時,這可以使用exec()eval()compile()等實現完美工作。 以下示例僅適用於f1函數,不適用於f2 我得到“不能腌制類”代碼”。 有什么辦法解決嗎? 例如以不同方式使用多重處理? 還是使用其他包裝? 還是一些低級的東西? 不幸的是,由於整個應用程序的設計,將字符串傳遞給進程然后在進程內部進行編譯對我來說不是一個選擇(即代碼字符串“丟失”,只有編譯后的版本可用)。

import multiprocessing

def callf(f, a):
    exec(f, {'a': a})

if __name__ == "__main__":
    f = compile("print(a)", filename="<string>", mode="exec")
    callf(f, 10)  # this works
    process = multiprocessing.Process(target=callf, args=(f, 20))  # this does not work
    process.start()
    process.join()

更新:這是另一種嘗試,實際上更接近我的實際需求。 這會導致出現不同的錯誤消息,但也不會使該函數出錯。

import multiprocessing

if __name__ == "__main__":
    source = "def f(): print('done')"
    locals = dict()
    exec(source, {}, locals)
    f = locals['f']
    f()  # this works
    process = multiprocessing.Process(target=f)  # this does not work
    process.start()
    process.join()

pickle不能序列化代碼對象,但dill可以。 有一個基於蒔蘿的多處理分支,稱為multiprocessing_on_dill,但我不知道它有多好。 您也可以對代碼對象進行蒔蘿編碼,以使標准的多處理過程變得愉快。

import multiprocessing
import dill

def callf_dilled(f_dilled, a):
    return callf(dill.loads(f_dilled), a)

def callf(f, a):
    exec(f, {'a': a})

if __name__ == "__main__":
    f = compile("print(a)", filename="<string>", mode="exec")
    callf(f, 10)  # this works
    process = multiprocessing.Process(target=callf_dilled, 
        args=(dill.dumps(f), 20))  # now this works too!
    process.start()
    process.join()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM