Быстрый тест показывает, что 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.
Приемлемый ответ – это, конечно, уверенное Нет.
pickle
сериализация/десериализация касается объектов Python, к которым могут иметь доступ другие потоки, она должна задействовать GIL. - person juanpa.arrivillaga   schedule 14.11.2019