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

Rust Winit事件循环运行过频,MacOS CPU占用过高求助

Winit应用MacOS下CPU跑满问题的解决

问题根源

你代码里的核心问题是:每次MainEventsCleared事件触发时都调用window.request_redraw(),这会立刻生成一个RedrawRequested事件,直接把事件循环从wait_until的等待状态唤醒。事件循环会陷入无限循环:MainEventsCleared请求重绘→触发RedrawRequested→处理完后立刻回到循环→再次进入MainEventsCleared又请求重绘,完全无视你设置的1秒等待,自然占满一个CPU核心。

去掉request_redraw()后,没有额外事件唤醒循环,所以wait_until正常工作,CPU占用就降下来了。

正确的定时重绘实现

要实现每1秒一次重绘,你需要把重绘请求和定时逻辑绑定,而不是在MainEventsCleared里无条件调用。示例代码如下:

use std::time::{Duration, Instant};
use winit::{event::Event, event_loop::ControlFlow, window::Window};

// 初始化下一次重绘的时间点
let mut next_redraw = Instant::now() + Duration::from_millis(1000);

event_loop.run(move |event, _, control_flow| {
    match event {
        Event::WindowEvent { .. } => {},
        Event::MainEventsCleared => {
            let now = Instant::now();
            // 到了定时点才请求重绘
            if now >= next_redraw {
                window.request_redraw();
                next_redraw = now + Duration::from_millis(1000);
            }
            // 让事件循环等待到下一次重绘时间
            control_flow.set_wait_until(next_redraw);
        },
        Event::RedrawRequested(_) => {
            // 在这里执行实际的渲染逻辑
        },
        _ => {}
    }
});

这样修改后,事件循环只会在到了指定时间才被唤醒,不会被无意义的重绘请求打断,CPU占用会恢复正常。

其他限制循环频率的方法

  • 精准控制ControlFlow:始终用set_wait_until指定明确的唤醒时间,避免触发额外的唤醒事件(比如无意义的request_redraw、多余的窗口事件)。
  • 按需触发重绘:只在真正需要更新画面的时候调用request_redraw(比如数据变化、用户交互后),而不是定时主动请求,让事件循环在空闲时保持等待状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:08:13