Има ли начин за сериализиране/десериализиране без ангажиране на 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 GB данни в секунда от работните процеси обратно към главния. Мога да премествам данните със сокети за поточно предаване и asyncio при 4GB/sec, но десериализацията е тясно място. За съжаление все още не разполагам с лукса на 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