Python: способы синхронизации задач трио и обычных потоков
Я нахожусь в ситуации, когда мне нужно синхронизировать задачи Trio с потоками Python. На данный момент я использую threading.Lock
объекты, которые задачи Трио должны приобрести с trio.run_sync_in_worker_thread(lock.acquire)
,
Я думаю, что это также должно быть возможно использовать trio. Lock
замки и нити приобретают их с trio.BlockingTrioPortal.run_sync(lock.acquire)
,
Обладает ли одно из этих решений преимуществами перед другим?
Будет ли в принципе возможно сделать лучше, чем это? Например, реализовать "родной" метод трио, который ожидает threading.Lock
без необходимости отдельного рабочего потока, или есть фундаментальные причины, почему это требуется?
2 ответа
Оба метода в порядке. Я бы рекомендовал использовать метод, который вызывает меньше работы, то есть, если внешний поток получает блокировку десять раз за задачу трио, затем используйте блокировку потока, и наоборот.
threading.Lock
всегда блокирует поток, пытаясь получить его, поэтому для его извлечения из Trio требуется либо отдельный поток (что ваш первый метод уже делает в любом случае), либо держатель замка должен сигнализировать задаче Trio, что он снял блокировку (который ваш второй метод) в любом случае), поэтому нет явного преимущества для реализации решения более низкого уровня.
Ответ Матиаса превосходен. Чтобы добавить: есть одно теоретическое преимущество использования trio.Lock
Это означает, что по крайней мере вызовы на стороне трио будут поддерживать отмену. Однако в настоящее время существует также серьезное практическое препятствие, заключающееся в том, что в настоящее время BlockingTrioPortal
звонить lock.acquire
а также lock.release
не работает:-(. См. эту проблему, которую я только что подал для деталей. Так что, пока это не исправлено, вам придется использовать threading.Lock
а также run_sync_in_worker_thread
, После исправления я бы по умолчанию использовал trio.Lock
за отмену.
РЕДАКТИРОВАТЬ: при дальнейшей мысли, я вспомнил, что трио уже имеет версию Lock
это работает с BlockingTrioPortal
Непонятно trio.Semaphore(1, max_value=1)
, Мы все еще должны исправить общий случай, но в то же время это может быть полезно знать.