Python: способы синхронизации задач трио и обычных потоков

1

Я оказался в ситуации, когда мне нужно синхронизировать задачи Trio с потоками Python. На данный момент я использую threading.Lock объекты, которые Trio задачи должны приобретать с trio.run_sync_in_worker_thread(lock.acquire).

Я думаю, что также можно использовать trio. Lock trio. Lock блокировки и получайте их с помощью trio.BlockingTrioPortal.run_sync(lock.acquire).

Имеет ли одно из этих решений преимущество над другим?

Можно ли в принципе сделать лучше, чем это? Например, для реализации "родного" метода трио, который ждет threading.Lock без необходимости отдельного рабочего потока или есть фундаментальные причины, почему это требуется?

  • 0
    Вы имеете в виду trio.BlockingTrioPortal.run(lock.acquire) поскольку trio.Lock.acquire является асинхронным методом.
Теги:
multithreading
python-trio

2 ответа

1
Лучший ответ

Оба метода в порядке. Я бы рекомендовал использовать метод, который вызывает меньше работы, т.е. Если внешний поток получает блокировку по десять раз за одно задание Trio, затем используйте блокировку потока и наоборот.

threading.Lock всегда блокирует поток, пытаясь его приобрести, поэтому для его получения из Trio требуется отдельный поток (который ваш первый метод уже делает в любом случае), или владелец блокировки должен сигнализировать о задаче Trio о том, что он освободил блокировку ( который ваш второй метод делает в любом случае), поэтому нет явного преимущества для реализации решения более низкого уровня.

1

Маттиас отвечает отлично. Чтобы добавить: есть одно теоретическое преимущество использования trio.Lock, то есть, то, по крайней мере, вызовы Trio-side будут поддерживать отмену. Однако в настоящее время существует и основное практическое препятствие, которое заключается в том, что в настоящее время, используя BlockingTrioPortal для вызова lock.acquire и lock.release, не работает :-(. См. Эту проблему, которую я только что написал для получения подробностей. 'll придется использовать threading.Lock и run_sync_in_worker_thread его исправления, я бы по умолчанию использовал trio.Lock для аннулирования.

EDIT: при дальнейшей мысли я вспомнил, что у трио уже есть версия Lock которая работает с BlockingTrioPortal, она просто trio.Semaphore(1, max_value=1): trio.Semaphore(1, max_value=1). Мы все равно должны исправить общий случай, но в то же время это может быть полезной вещью.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню