You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程双定时器:同步运行、重置实现及输出闪烁问题解决

双定时器同步、输出闪烁及重置功能解决方法

一、输出闪烁的原因及解决办法

原因

两个子进程同时用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)} 秒。")

重置逻辑说明

  1. 每个定时器对应一个Event对象,作为重置信号;
  2. 主进程检测到特定条件(比如用户输入、时间阈值)时,调用reset_event.set()发送重置信号;
  3. 子进程循环中检查信号,收到后将当前计时值恢复为初始值,清除信号后继续计时;
  4. 如果要同时重置两个定时器,只需同时触发两个Event即可。

内容的提问来源于stack exchange,提问作者ARKAJEET BASAK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:05:25