Перейдите к своему config.php
. У меня такая же проблема. Проверьте имя пользователя и пароль, а также sql select - это то же имя, что и config.
Использование multiprocessing
требует отправки рабочим процессам информации о выполняемой функции, а не только аргументы для передачи. Эта информация передается травлением , что информация в основном процессе, отправка его в рабочий процесс и ее рассыпание.
Это приводит к основной проблеме:
Травление функции с аргументами по умолчанию дешево; он только замачивает имя функции (плюс информация, чтобы Python знал, что это функция); рабочие процессы просто ищут локальную копию имени. У них уже есть именованная функция f
, чтобы найти ее, поэтому ей почти ничего не стоит.
Но травление функции partial
включает в себя травление основной функции (дешево) и всех аргументы по умолчанию ( дорогие , когда аргумент по умолчанию - 10M list
). Поэтому каждый раз, когда задача отправляется в случае partial
, она травит связанный аргумент, отправляет его в рабочий процесс, рабочий процесс распаковывается, а затем выполняет «настоящую» работу. На моей машине этот рассол имеет размер примерно 50 МБ, что является огромным объемом накладных расходов; в быстрых тестах времени на моей машине, травление и рассыпание 10 миллионов длинной list
из 0
занимает около 620 мс (и это игнорирует накладные расходы на фактическую передачу 50 МБ данных).
partial
должны рассосаться таким образом, потому что они не знают своих имен; при расчете функции, подобной f
, f
(будучи def
-ed) знает свое квалифицированное имя (в интерактивном интерпретаторе или из основного модуля программы это __main__.f
), поэтому удаленная сторона может просто воссоздайте его локально, выполнив эквивалент from __main__ import f
. Но partial
не знает его имени; конечно, вы назначили его g
, но ни pickle
, ни partial
сами не знают, что это доступно с квалифицированным именем __main__.g
; его можно было бы назвать foo.fred
или миллион других вещей. Поэтому он должен pickle
получить информацию, необходимую для воссоздания целиком с нуля. Это также pickle
для каждого вызова (не один раз на одного рабочего), потому что он не знает, что вызываемый не меняет родителя между рабочими элементами, и он всегда пытается обеспечить его отправку в актуальное состояние.
У вас есть другие проблемы (создание временного времени для list
только в случае partial
и незначительные накладные расходы при вызове функции partial
, завершенной или вызывающей функцию напрямую), но это chump изменение относительно накладного травления для каждого вызова и разблокировка partial
добавляется (первоначальное создание list
добавляет одноразовые служебные данные чуть ниже половины того, что каждый цикл pickle / unpickle расходы, накладные расходы для вызова через partial
меньше, чем микросекунда).