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), Мы все еще должны исправить общий случай, но в то же время это может быть полезно знать.

Другие вопросы по тегам