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