为何sleep在所有输出前执行,而非穿插在打印语句之间运行?
问题原因
你遇到的是Lisp实现默认的输出缓冲机制导致的问题:绝大多数Lisp实现对标准输出默认启用行缓冲或全缓冲,只有缓冲被填满、遇到换行符、或是程序退出时才会将缓冲内的内容输出到终端。你代码中每次print的内容会暂存在缓冲中,sleep过程中不会触发缓冲刷新,直到程序运行结束才会一次性打印所有内容。
你之前调用finish-output无效通常是因为没有指定需要刷新的目标流,或是调用位置不对。
解决方案
方案1:每次打印后手动刷新输出流
每次执行打印操作后,明确调用finish-output刷新标准输出流即可,修改后代码如下:
(print "test") (finish-output *standard-output*) (sleep 1) (print "test 2") (finish-output *standard-output*) (sleep 1) (print "test 3") (finish-output *standard-output*)
如果需要兼容更多场景,也可以将finish-output替换为force-output,前者会等待所有输出完成再返回,后者仅触发刷新操作不等待完成,对于普通打印场景两者效果一致。
方案2:全局修改标准输出的缓冲策略
如果你不想每次打印后都手动刷新,可以在程序开头直接修改标准输出的缓冲模式,关闭缓冲或启用行缓冲,不同Lisp实现的设置方式略有区别:
- SBCL:
(setf (sb-impl::stream-buffering *standard-output*) :none) - Clozure CL:
(setf (ccl:stream-output-buffering *standard-output*) nil)
设置后所有打印操作都会实时输出,不需要额外调用刷新函数。
内容的提问来源于stack exchange,提问作者Cal
相关产品推荐
相关产品推荐

