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
相关产品推荐
相关产品推荐

