为何Python定时调用函数的代码会冻结?添加print却正常?
问题分析:为何前两个定时执行函数冻结,添加print后正常?
先看用户的代码实现:
from time import time def multiply(n1, n2): return n1 * n2 # 导致程序冻结(CASE 1) def not_working_1_timed_exec(func, sec, *args, **kwargs): start = time() while time() - start < sec: yield func(*args, **kwargs) # print(list(not_working_1_timed_exec(multiply, 5, 2, 5))) # 导致程序冻结(CASE 2) def not_working_2_timed_exec(func, sec, *args, **kwargs): start = time() ret = [] while time() - start < sec: ret.append(func(*args, **kwargs)) return ret # print(list(not_working_2_timed_exec(multiply, 5, 2, 5))) # 正常运行 def timed_exec(func, sec, *args, **kwargs): start = time() while time() - start < sec: print('hello world') # 这行让函数正常工作 yield func(*args, **kwargs) print(list(timed_exec(multiply, 5, 2, 5)))
为什么前两个函数会导致冻结?
这两个函数的核心问题是循环密度太高,完全占满了CPU:
- CASE1的生成器版本:当用
list()遍历生成器时,生成器会在while循环里疯狂执行multiply并yield结果。因为multiply是极简单的计算函数,执行速度极快,循环会在指定时长内把CPU拉满到100%,系统没有多余资源处理界面响应、输出缓冲等其他任务,程序因此看起来像“冻结”。 - CASE2的列表版本:原理完全一致,while循环里疯狂调用
multiply并将结果存入列表,CPU被计算任务彻底占用,系统无法处理其他操作,自然无响应。
为什么print语句能让函数正常工作?
print在这里起到了两个关键作用:
- 触发IO操作,给CPU喘息时间:print属于标准输出的IO操作,这类任务速度远慢于计算,CPU在等待输出完成的间隙,会去处理系统的其他任务(比如响应程序状态、刷新界面等),不会被计算循环完全占死。
- 引入微小延迟:IO操作本身会带来极短的延迟,虽然感知不到,但足够降低循环频率,避免CPU持续100%占用,程序也就不会出现冻结现象。
其实不用print也能解决问题,比如在循环里加一行time.sleep(0.001),给循环加个微秒级延迟,同样能让CPU释放资源,恢复程序正常运行。
内容的提问来源于stack exchange,提问作者Omer Menahse
相关产品推荐
相关产品推荐

