Есть ли способ внедрить python, разрешить обратные вызовы с python на C++, разрешить коду Python создавать потоки и избежать взаимоблокировок?
Проблема в следующем:
Чтобы вызвать Python, мне нужно удерживать GIL. Как правило, я делаю это, получая состояние основного потока при первом создании интерпретатора, а затем использую PyEval_RestoreThread() для получения GIL и замены состояния потока перед вызовом Python.
При вызове из Python мне может понадобиться доступ к некоторым защищенным ресурсам, которые защищены отдельным критическим разделом на моем хосте. Это означает, что Python будет удерживать GIL (возможно, из какого-то другого потока, а не того, который я изначально вызывал), а затем попытается получить мою защитную блокировку.
При вызове Python мне может потребоваться удерживать те же блокировки, потому что, например, я могу перебирать некоторую коллекцию объектов.
Проблема в том, что даже если я держу GIL при вызове Python, Python может отказаться от него, передать его другому потоку, а затем вызвать этот поток на мой хост, ожидая получить блокировки хоста. Тем временем хост может взять блокировки хоста и блокировку GIL и вызвать Python. Наступает тупик.
Проблема здесь в том, что Python передает GIL другому потоку, пока я вызываю его. Это то, что он должен делать, но делает невозможным блокировку последовательности - даже если я сначала возьму GIL, затем возьму свою собственную блокировку, а затем вызову Python, Python вызовет мою систему из другого потока, ожидая получить мою собственную блокировку (потому что он распаковал GIL, выпустив его).
Я не могу заставить остальную часть моей системы использовать GIL для всех возможных блокировок в системе — и это даже не сработает правильно, потому что Python все еще может освободить его для другого потока.
Я также не могу гарантировать, что мой хост не блокирует никаких блокировок при входе в Python, потому что я не контролирую весь код на хосте.
Так что, это просто случай, когда это невозможно сделать?