Почему GIL не синхронизирует потоки Python, которые выполняют собственный код C ++ внутри DLL? - PullRequest
0 голосов
/ 19 декабря 2018

Я разработал простое многопоточное приложение Python (Python 3.7) для вызова 8 различных ресурсоемких задач в 8 потоках.Задачи могут быть либо кодом Python, либо кодом C ++, который встроен в DLL и доступен через пакет ctypes.Я провожу эксперименты на 8-ядерном компьютере под Windows.

Странно, что когда все потоки вызывают код Python, кажется, что в определенный момент времени активен только один поток, а загрузка ЦП составляет около 12,5%.Но при вызове кода C ++ внутри DLL используются все ядра, а загрузка ЦП составляет 100%.

Теперь возникает вопрос: почему GIL (Global Interpreter Lock) не синхронизирует потоки Python, которые вызывают собственные коды C ++?Разве реализация ctypes освобождает GIL при вызове собственного кода C ++?

Edit 1: Никакой макрос, подобный Py_BEGIN_ALLOW_THREADS , используется в Native C ++ DLL.

1 Ответ

0 голосов
/ 19 декабря 2018

С [Python 3]: ctypes - загрузка общих библиотек ( выделение принадлежит мне; спасибо @ user2357112 за указание на эту очень явную цитату (лучше, чем то, что я изначальноотправлено)):

Глобальная блокировка интерпретатора Python освобождается перед вызовом любой функции, экспортируемой этими библиотеками, а затем повторно запрашивается .

Вы также можете найти это утверждение в других формах на той же странице (отметьте PyDLL , CFUNCTYPE ).

Существуют способы обхода GIL ограничение:

  • Замена использования модуля threading на multiprocessing ( [Python 3]: multiprocessing -Процессный параллелизм ).Это наиболее распространенный

  • Включение блоков кода, которые могут выполняться параллельно в Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS .Недостатком будет то, что .dll будет зависеть от Python

...