Lean 4(元)编程 Cookbook

进程中断与空闲休眠🔗

Lean 4 提供了若干机制来管理并发任务并处理中断。本节探讨如何实现可中断的休眠,以及等待外部信号的“空闲”状态。让进程休眠的方法参见 让进程休眠

可中断的休眠(“换班”模式)🔗

一个常见需求是让线程休眠一段时间,但允许在时间到期之前被“唤醒”或中断。在 Lean 中,这可以用 IO.Promise 实现,见参考文档IO.Promise 是一种同步原语,允许一个线程等待由另一个线程稍后提供的值。在这里,它充当一个“信号”或“信箱”,休眠的线程在其中等待承诺(promise)被兑现,从而让外部触发能够中断这次等待。

使用额外的任务(超时任务)🔗

这种方法会派生一个独立的任务,在延迟后兑现一个承诺。主工作者等待同一个承诺。

def interruptibleWorker (p : IO.Promise Bool) : IO Unit := do IO.println "Worker: starting sleep (10s timeout)..." let timeoutTask IO.asTask do IO.sleep 10000 -- Resolve with 'false' to indicate timeout p.resolve false -- Wait for the promise to be resolved -- (either by timeout or interrupt) let interrupted IO.wait p.result! -- CRITICAL: Cancel the timeout task -- so the process can exit immediately IO.cancel timeoutTask if interrupted then IO.println "Worker: interrupted early!" else IO.println "Worker: finished naturally (timeout)."

使用 IO.waitAny(逻辑上不需要额外的任务)🔗

如果你已经有多个任务在运行,并且想等待其中第一个完成的(或某个特定的“中断”任务),可以使用 IO.waitAny

def waitFirst (t1 t2 : Task α) : IO α := do IO.waitAny [t1, t2]

你也可以用 IO.waitAny 实现一个超时机制,让一个计算任务与一个计时器任务竞速。

/-- Waits for a task to complete or returns a default value after a delay. -/ def waitWithTimeout {α : Type} (action : Task α) (timeoutMs : UInt32) (default : α) : IO α := do let timer BaseIO.asTask (do IO.sleep timeoutMs pure default ) let finished IO.waitAny [action, timer] return finished

应用:中断空闲休眠(类操作系统的休眠)🔗

“空闲休眠”是这样一种状态:进程什么都不做,消耗极少资源,直到被某个外部事件(如一个信号或一条消息)显式唤醒。

在 Lean 中,你可以通过等待一个没有关联超时任务的承诺来实现它。

def idleProcess (wakeUpSignal : IO.Promise Unit) : IO Unit := do IO.println "Process entering idle state..." -- This will block indefinitely until -- wakeUpSignal.resolve () is called let _ IO.wait wakeUpSignal.result! IO.println "Process woken up! Resuming execution..." def runSystem : IO Unit := do let signal IO.Promise.new let procTask IO.asTask (idleProcess signal) IO.println "System running... doing other work." IO.sleep 3000 IO.println "Main: Triggering wake-up signal." signal.resolve () let _ IO.wait procTask IO.println "System shutdown."

在这种模式下,“休眠”是真正空闲的;没有计时器在运行。进程只是让出,直到承诺被系统的另一部分兑现。