Есть ли способ сериализовать/десериализовать без использования python GIL

Быстрый тест показывает, что cPickle (python 3.6.9 import pickle по умолчанию используется cPickle) задействует GIL.

import pickle
import os

big_data = os.urandom(10000000)

def run():
    pickle.loads(pickle.dumps(big_data))

t = timeit.Timer(run)
[threading.Thread(target=lambda: t.timeit(number=2000)).start() for _ in range(4)]

Этот тест из 4 потоков, выполняющих операции сериализации, выполняется на 100% процессоре, например. он задействует GIL. Тот же тип теста, выполняющий операцию numpy, использует 400% процессора (GIL не задействован с numpy).

Я надеялся, что cPickle, будучи функцией C, не задействует GIL. Есть ли способ обойти это? Я хотел бы иметь возможность десериализовать большой объем данных, не блокируя основной процесс.

Я пытаюсь получить более 3 ГБ данных в секунду из рабочих процессов обратно в основной. Я могу перемещать данные с помощью потоковых сокетов и asyncio со скоростью 4 ГБ/с, но десериализация является узким местом. К сожалению, у меня пока нет такой роскоши, как Python 3.8 и SharedMemory.

Приемлемый ответ – это, конечно, уверенное Нет.


person David Parks    schedule 13.11.2019    source источник
comment
Я не понимаю, почему тот факт, что модуль является C-расширением, должен заставить вас думать, что он не задействует GIL. Насколько я понимаю, фундаментальная проблема, которую решает GIL, — это потокобезопасный доступ к объектам уровня интерпретатора Python, которые полагаются на подсчет ссылок для сборки мусора. Поскольку pickle сериализация/десериализация касается объектов Python, к которым могут иметь доступ другие потоки, она должна задействовать GIL.   -  person juanpa.arrivillaga    schedule 14.11.2019
comment
@juanpa.arrivillaga Я приму это, если вы опубликуете это как ответ. Ваше объяснение звучит, скорее всего, правильно. Я приравнивал функции C к внешним функциям, которые могут выпускать GIL, как это делает numpy, но, как вы указываете, это не кажется разумным в случае сериализации объектов Python.   -  person David Parks    schedule 14.11.2019


Ответы (1)


Взяв ответ @juanpa.arrivillaga из комментариев, чтобы закрыть этот вопрос:

Я не понимаю, почему тот факт, что модуль является C-расширением, должен заставить вас думать, что он не задействует GIL. Насколько я понимаю, фундаментальная проблема, которую решает GIL, — это потокобезопасный доступ к объектам уровня интерпретатора Python, которые полагаются на подсчет ссылок для сборки мусора. Поскольку сериализация/десериализация pickle затрагивает объекты Python, к которым могут иметь доступ другие потоки, она должна задействовать GIL.

person David Parks    schedule 03.02.2020