Я использую сервер Flask для обработки запросов на некоторые задачи обработки изображений.
Обработка в значительной степени зависит от OpenCV, и теперь я хотел бы тривиально распараллелить некоторые из более медленных шагов.
Я предпочитаю многопроцессорность, а не многопоточность (пожалуйста, примите первое в ваших ответах).
Но многопроцессорность с opencv явно не работает (я на Python 2.7 + macOS): https://github.com/opencv/opencv/issues/5150
Одним из решений (см. https://github.com/opencv/opencv/issues/5150#issuecomment-400727184) является использование превосходного Loky (https://github.com/tomMoral/loky)
[Вопрос: Какие существуют другие рабочие решения, кроме concurrent.futures
, loky
, joblib
..?]
Но Локи приводит меня к следующей трассировке стека:
a,b = f.result()
File "/anaconda2/lib/python2.7/site-packages/loky/_base.py", line 433, in result
return self.__get_result()
File "/anaconda2/lib/python2.7/site-packages/loky/_base.py", line 381, in __get_result
raise self._exception
BrokenProcessPool: A task has failed to un-serialize. Please ensure that the arguments of the function are all picklable.
This was caused directly by
'''
Traceback (most recent call last):
File "/anaconda2/lib/python2.7/site-packages/loky/process_executor.py", line 391, in _process_worker
call_item = call_queue.get(block=True, timeout=timeout)
File "/anaconda2/lib/python2.7/multiprocessing/queues.py", line 135, in get
res = self._recv()
File "myfile.py", line 44, in <module>
app.config['EXECUTOR_MAX_WORKERS'] = 5
File "/anaconda2/lib/python2.7/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "/anaconda2/lib/python2.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/anaconda2/lib/python2.7/site-packages/flask/globals.py", line 52, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
'''
Функции, которые должны быть распараллелены, вызываются не из app/main.py
, а скорее из подмодуля глубоко подмодуля.
Я попробовал похожий на полезный вид https://flask -executor.readthedocs.io / en / latest , также пока безрезультатно.
Так что вопрос:
Как ся безопасно передаю контекст приложения рабочим или иным образом получаю многопроцессорную работу (без обращения к многопоточности)?
Я могу задать этот вопрос, если вам потребуется дополнительная информация.Большое спасибо как всегда.
Связанные ресурсы:
Скопировать запрос флешки / контекст приложения в другой процесс
Многопроцессорная обработка колбы
Обновление:
Не-opencv-вызовы прекрасно работают с flask-executor (no Loky):)
Проблема возникает при попытке вызвать opencvфункция вроде knnMatch
.
Если Loky исправляет проблему с opencv, мне интересно, можно ли ее заставить работать с flask-executor (пока не для меня).