我想在循环中运行两部分代码。有时我需要让循环'睡眠',使每次迭代跳过第二部分。循环应该在一段时间后停止休眠(例如使用调用thread::sleep
的线程)。我该如何做到这一点?
use std::thread;
let mut sleeping = false;
let mut handle = thread::spawn(|| {});
loop {
part_1();
if sleeping {
continue;
}
part_2();
if some_condition {
sleeping = true;
handle = thread::spawn(|| thread::sleep_ms(100));
}
}
在此示例中,如果满足条件,则会跳过part_2
次调用以进行一定量的迭代。我的用例是继续在游戏中运行图形更新,同时冻结游戏的逻辑(例如倒计时器)。
答案 0 :(得分:2)
不需要线程开销,甚至不需要睡眠。只需跟踪延迟执行代码的时间,直到:
dll
虽然我可能在这里避免使用use std::time::{Duration, Instant};
fn part_1() {}
fn part_2() {}
fn some_condition() -> bool {
false
}
fn main() {
let mut sleep_until = None;
loop {
part_1();
if let Some(until) = sleep_until {
if until > Instant::now() {
continue;
}
}
part_2();
if some_condition() {
let now = Instant::now();
let until = now + Duration::from_millis(500);
sleep_until = Some(until);
}
}
}
,而是将逻辑嵌入:
continue
注意在一个案例中我使用use std::time::{Duration, Instant};
fn perform_physics_calculation() {}
fn perform_graphics_render() {}
fn main() {
let mut next_graphics_update = Instant::now();
let graphics_delay = Duration::from_millis(500);
loop {
let now = Instant::now();
perform_physics_calculation();
if next_graphics_update <= now {
perform_graphics_render();
next_graphics_update = now + graphics_delay;
}
}
}
而在另一个案例中我只使用Option<Instant>
;两种情况都有意义。
答案 1 :(得分:1)
将sleeping
变量转换为引用计数的原子布尔值,以便您可以在休眠线程上重置它。
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::time::Duration;
fn part_1() {}
fn part_2() {}
fn some_condition() -> bool { false }
fn main() {
let sleeping = Arc::new(AtomicBool::new(false));
let mut handle = None;
loop {
part_1();
if sleeping.load(Ordering::Acquire) {
continue;
}
part_2();
if some_condition() {
sleeping.store(true, Ordering::Release);
let sleeping_clone = sleeping.clone();
handle = Some(thread::spawn(move || {
thread::sleep(Duration::from_millis(100));
sleeping_clone.store(false, Ordering::Release);
}));
}
}
}