多进程双定时器:同步运行、重置实现及输出闪烁问题解决
双定时器同步、输出闪烁及重置功能解决方法
一、输出闪烁的原因及解决办法
原因
两个子进程同时用print(timer, end='\r')往控制台输出,\r会把光标移到行首,但两个进程的输出会互相覆盖,导致屏幕上的时间值被频繁交替刷新,就出现了闪烁。
解决办法
让主进程统一管理输出,用multiprocessing.Queue让子进程把当前计时状态传给主进程,由主进程一次性打印两个定时器的状态,避免互相干扰。修改后的代码如下:
import time import multiprocessing def countdown(u, queue, process_id): while u: mins, sec = divmod(u, 60) timer = '{:02d}:{:02d}'.format(mins, sec) queue.put((process_id, timer)) # 把进程ID和当前时间传入队列 time.sleep(1) u -= 1 queue.put((process_id, "已结束")) # 定时器完成标记 if __name__ == '__main__': start = time.perf_counter() queue = multiprocessing.Queue() p1 = multiprocessing.Process(target=countdown, args=[10, queue, 1]) p2 = multiprocessing.Process(target=countdown, args=[11, queue, 2]) p1.start() p2.start() # 保存两个定时器的当前状态 timer_states = {1: "", 2: ""} active_processes = 2 while active_processes > 0: process_id, state = queue.get() if state == "已结束": active_processes -= 1 timer_states[process_id] = "已结束" else: timer_states[process_id] = state # 主进程统一打印,避免交替覆盖 print(f"定时器1: {timer_states[1]} | 定时器2: {timer_states[2]}", end='\r') p1.join() p2.join() finish = time.perf_counter() print(f"\n整个过程耗时 {round(finish-start, 2)} 秒。")
二、实现定时器重置功能
多进程之间内存不共享,没法直接修改子进程的变量,所以用multiprocessing.Event做重置信号,配合队列实现。以下是示例代码:
import time import multiprocessing def countdown(u, queue, reset_event, process_id): current_time = u while True: # 检查是否收到重置信号 if reset_event.is_set(): current_time = u # 恢复初始计时值 reset_event.clear() # 清除信号,避免重复重置 if current_time <= 0: queue.put((process_id, "已结束")) break mins, sec = divmod(current_time, 60) timer = '{:02d}:{:02d}'.format(mins, sec) queue.put((process_id, timer)) time.sleep(1) current_time -= 1 if __name__ == '__main__': start = time.perf_counter() queue = multiprocessing.Queue() # 为每个定时器创建重置信号 reset_event1 = multiprocessing.Event() reset_event2 = multiprocessing.Event() p1 = multiprocessing.Process(target=countdown, args=[10, queue, reset_event1, 1]) p2 = multiprocessing.Process(target=countdown, args=[11, queue, reset_event2, 2]) p1.start() p2.start() timer_states = {1: "", 2: ""} active_processes = 2 reset_triggered = False while active_processes > 0: # 模拟特定条件触发重置(这里以运行3秒为例) if time.perf_counter() - start >= 3 and not reset_triggered: print("\n触发定时器重置...") reset_event1.set() reset_event2.set() reset_triggered = True process_id, state = queue.get() if state == "已结束": active_processes -= 1 timer_states[process_id] = "已结束" else: timer_states[process_id] = state print(f"定时器1: {timer_states[1]} | 定时器2: {timer_states[2]}", end='\r') p1.join() p2.join() finish = time.perf_counter() print(f"\n整个过程耗时 {round(finish-start, 2)} 秒。")
重置逻辑说明
- 每个定时器对应一个
Event对象,作为重置信号; - 主进程检测到特定条件(比如用户输入、时间阈值)时,调用
reset_event.set()发送重置信号; - 子进程循环中检查信号,收到后将当前计时值恢复为初始值,清除信号后继续计时;
- 如果要同时重置两个定时器,只需同时触发两个
Event即可。
内容的提问来源于stack exchange,提问作者ARKAJEET BASAK
相关产品推荐
相关产品推荐

