_multiprocessing.SemLock не реализован при работе на AWS Lambda

У меня есть короткий код, который использует пакет multiprocessing и отлично работает на моем локальном компьютере.

Когда я загрузил на AWS Lambda и запустил там, я получил следующую ошибку (stacktrace обрезан):

[Errno 38] Function not implemented: OSError
Traceback (most recent call last):
  File "/var/task/recorder.py", line 41, in record
    pool = multiprocessing.Pool(10)
  File "/usr/lib64/python2.7/multiprocessing/__init__.py", line 232, in Pool
    return Pool(processes, initializer, initargs, maxtasksperchild)
  File "/usr/lib64/python2.7/multiprocessing/pool.py", line 138, in __init__
    self._setup_queues()
  File "/usr/lib64/python2.7/multiprocessing/pool.py", line 234, in _setup_queues
    self._inqueue = SimpleQueue()
  File "/usr/lib64/python2.7/multiprocessing/queues.py", line 354, in __init__
    self._rlock = Lock()
  File "/usr/lib64/python2.7/multiprocessing/synchronize.py", line 147, in __init__
    SemLock.__init__(self, SEMAPHORE, 1, 1)
  File "/usr/lib64/python2.7/multiprocessing/synchronize.py", line 75, in __init__
    sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
OSError: [Errno 38] Function not implemented

Может ли быть так, что часть основных пакетов Python не реализована? Я понятия не имею, на чем я работаю внизу, поэтому я не могу войти туда и отладить.

Любые идеи, как я могу запустить multiprocessing на Lambda?


person Zach Moshe    schedule 30.11.2015    source источник
comment
Возможный дубликат OSError 38 [Errno 38] с многопроцессорной обработкой   -  person 200_success    schedule 13.06.2018


Ответы (5)


Насколько я могу судить, многопроцессорность не будет работать на AWS Lambda, поскольку отсутствует среда выполнения/контейнер /dev/shm — см. https://forums.aws.amazon.com/thread.jspa?threadID=219962 (может потребоваться авторизация).

Нет слов (что я могу найти) о том, изменит ли / когда Amazon это. Я также посмотрел на другие библиотеки, например. https://pythonhosted.org/joblib/parallel.html вернется к /tmp (которое, как мы знаем, СУЩЕСТВУЕТ), если он не может найти /dev/shm, но на самом деле это не решает проблему.

person glennji    schedule 01.12.2015
comment
Не могли бы вы рассказать, как решить эту проблему с помощью joblib? Я тестирую это прямо сейчас, и joblib возвращается к последовательным операциям: [Errno 38] Function not implemented. joblib will operate in serial mode - person pjgranahan; 17.03.2017
comment
Эта ветка предполагает, что joblib на самом деле не может решить эту проблему. - person pjgranahan; 17.03.2017
comment
Да, извините, я никогда не копал достаточно глубоко в этом. Вполне может быть нерабочим. - person glennji; 21.03.2017
comment
Пожалуйста, обновите свой ответ. Это выглядит обманчиво, пока посетитель не прочитает комментарии. - person Mohamed Taher Alrefaie; 30.07.2018

Вы можете запускать процедуры параллельно на AWS Lambda, используя модуль многопроцессорности Python, но вы не можете использовать пулы или очереди, как указано в других ответах. Рабочим решением является использование Process и Pipe, как описано в этой статье https://aws.amazon.com/blogs/compute/parallel-processing-in-python-with-aws-lambda/

Хотя статья определенно помогла мне найти решение (описано ниже), есть несколько моментов, о которых следует знать. Во-первых, решение, основанное на процессах и конвейерах, работает не так быстро, как встроенная функция карты в пуле, хотя я заметил почти линейное ускорение, когда увеличил доступную память/ресурсы ЦП в моей функции Lambda. Во-вторых, при разработке функций многопроцессорной обработки таким образом необходимо выполнить определенные действия по управлению. Я подозреваю, что это, по крайней мере частично, почему мое решение медленнее, чем встроенные методы. Если у кого-то есть предложения по ускорению, буду рад их услышать! Наконец, хотя в статье отмечается, что многопроцессорность полезна для разгрузки асинхронных процессов, существуют и другие причины для использования многопроцессорности, такие как множество интенсивных математических операций, что я и пытался сделать. В конце концов, я был достаточно доволен улучшением производительности, так как это было намного лучше, чем последовательное выполнение!

Код:

# Python 3.6
from multiprocessing import Pipe, Process

def myWorkFunc(data, connection):
    result = None

    # Do some work and store it in result

    if result:
        connection.send([result])
    else:
        connection.send([None])


def myPipedMultiProcessFunc():

    # Get number of available logical cores
    plimit = multiprocessing.cpu_count()

    # Setup management variables
    results = []
    parent_conns = []
    processes = []
    pcount = 0
    pactive = []
    i = 0

    for data in iterable:
        # Create the pipe for parent-child process communication
        parent_conn, child_conn = Pipe()
        # create the process, pass data to be operated on and connection
        process = Process(target=myWorkFunc, args=(data, child_conn,))
        parent_conns.append(parent_conn)
        process.start()
        pcount += 1

        if pcount == plimit: # There is not currently room for another process
            # Wait until there are results in the Pipes
            finishedConns = multiprocessing.connection.wait(parent_conns)
            # Collect the results and remove the connection as processing
            # the connection again will lead to errors
            for conn in finishedConns:
                results.append(conn.recv()[0])
                parent_conns.remove(conn)
                # Decrement pcount so we can add a new process
                pcount -= 1

    # Ensure all remaining active processes have their results collected
    for conn in parent_conns:
        results.append(conn.recv()[0])
        conn.close()

    # Process results as needed
person E Morrow    schedule 14.09.2018
comment
Этот код немного сложно соблюдать. Является ли myPipedMultiProcessFunc жизнеспособной заменой Pool.map()? - person Alex R; 26.05.2019
comment
Как написано, myPipedMultiProcessFunc намного быстрее, чем запуск myWorkFunc в последовательном цикле. Прошло некоторое время с тех пор, как я написал это, но я помню, что эта реализация составляет около 80% скорости Pool.map(). С удовольствием отвечу, если в моем коде есть неясные фрагменты. - person E Morrow; 28.05.2019

Я столкнулся с той же проблемой. Это код, который у меня был ранее, который отлично работал на моей локальной машине:

import concurrent.futures


class Concurrent:

    @staticmethod
    def execute_concurrently(function, kwargs_list):
        results = []
        with concurrent.futures.ProcessPoolExecutor() as executor:
            for _, result in zip(kwargs_list, executor.map(function, kwargs_list)):
                results.append(result)
        return results

И я заменил его на этот:

import concurrent.futures


class Concurrent:

    @staticmethod
    def execute_concurrently(function, kwargs_list):
        results = []
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
            futures = [executor.submit(function, kwargs) for kwargs in kwargs_list]
        for future in concurrent.futures.as_completed(futures):
            results.append(future.result())
        return results

Работает как шарм.

Взято из этот запрос на включение

person Tomás Denis Reyes Sánchez    schedule 08.04.2020

multiprocessing.Pool и multiprocessing.Queue изначально не поддерживаются (из-за проблемы с SemLock), но multiprocessing.Process и multiprocessing.Pipe и т. д. работают правильно в AWSLambda.

Это должно позволить вам создать обходное решение, вручную создавая/разветвляя процессы и используя multiprocessing.Pipe для связи между родительским и дочерним процессами. надеюсь, это поможет

person whummer    schedule 09.01.2017
comment
multiprocessing.Queue у меня не работает, и я получаю ту же ошибку, что и в вопросе. - person Robin Elvin; 12.04.2017
comment
Очередь не работает, и вы не можете делать блокировки между процессами без /dev/shm - person Atifm; 08.06.2017

Вы можете обновить и использовать среду выполнения AWS Lambda Python 3.7. Работает на меня!

AWS Lambda поддерживает несколько языков благодаря использованию сред выполнения. Вы выбираете среду выполнения при создании функции, и вы можете изменить среды выполнения, обновив конфигурацию вашей функции. Базовая среда выполнения предоставляет дополнительные библиотеки и переменные среды, доступ к которым можно получить из кода функции.

person Andre Araujo    schedule 29.08.2020