Python: 同步三重任务和常规线程的方法

Python: ways to synchronize trio tasks and regular threads

我发现自己处于需要将 Trio 任务与 Python 线程同步的情况。目前,我正在使用 Trio 任务必须通过 trio.run_sync_in_worker_thread(lock.acquire).

获取的 threading.Lock 个对象

我认为也应该可以使用 trio. Lock 锁并让线程使用 trio.BlockingTrioPortal.run_sync(lock.acquire) 获取它们。

这些解决方案中的任何一个都比另一个有优势吗?

原则上是否可以做得比这更好?例如。实现等待 threading.Lock 的 "native" trio 方法而不需要单独的工作线程,或者是否有需要这样做的根本原因?

两种方法都可以。我建议使用导致较少工作的方法,即如果每个 Trio 任务一次外部线程获取十次锁,则使用线程锁,反之亦然。

A threading.Lock 总是阻塞试图获取它的线程,因此从 Trio 获取它要么需要一个单独的线程(无论如何你的第一个方法已经这样做了),要么锁的持有者需要向 Trio 任务发出信号它已经释放了锁(你的第二种方法无论如何都会这样做),因此实现较低级别的解决方案没有明显的优势。

Matthias 的回答非常好。补充一下:使用 trio.Lock 理论上有一个优势,那就是至少 Trio 端调用将支持取消。然而,目前还有一个主要的实际障碍,即目前,使用 BlockingTrioPortal 调用 lock.acquirelock.release 不起作用:-(。参见 this issue I just filed详细信息。因此,在修复之前,您必须使用 threading.Lockrun_sync_in_worker_thread。修复后,我会默认使用 trio.Lock 来取消。

编辑:经过进一步思考,我记得 trio 确实已经有一个与 BlockingTrioPortal 一起使用的 Lock 版本,它只是晦涩难懂:trio.Semaphore(1, max_value=1)。我们仍然应该修复一般情况,但与此同时,了解这可能是一件有用的事情。