Как вынести в impl блок кода, создающий отдельный поток?
Код, приведенный в первом блоке - работает.
Как вынести в отдельный impl
часть, которая создаёт отдельный поток?
Типа, как во втором блоке кода, где помечено, что так не работает
.
play_1
use std::time::{SystemTime, Instant};
use std::thread;
use thread::JoinHandle;
fn main() {
let handle: JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> = thread::spawn(|| {
let t21: SystemTime = SystemTime::now();
let start_02 = Instant::now();
let mut j: usize = 0;
loop {
if j == 10 { break; }
j = j + 1;
}
let t22: SystemTime = SystemTime::now();
let d2:(usize, SystemTime, SystemTime, core::time::Duration) = (j, t21, t22, start_02.elapsed());
d2
});
let t11: SystemTime = SystemTime::now();
let start_01 = Instant::now();
let mut i: usize = 0;
loop {
if i == 10 { break; }
i = i + 1;
}
let t12 = SystemTime::now();
let d2 = handle.join().expect("thread panicked :...");
println!("i = {:?} \nt11 = {:?} \nt12 = {:?}", i, t11, t12);
println!("dt_01 = {:?}\n", start_01.elapsed());
//
println!("j = {:?} \nt21 = {:?} \nt22 = {:?}", &d2.0, &d2.1, &d2.2);
println!("dt_02 = {:?}\n", &d2.3);
}
что-то типа такого:
play_2
use std::time::{SystemTime, Instant};
use std::thread;
use thread::JoinHandle;
struct Thd {
a: usize,
b: SystemTime,
c: SystemTime,
d: core::time::Duration,
}
impl Thd {
pub fn new() -> JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> {
thread::spawn(|| {
let t21: SystemTime = SystemTime::now();
let start_02 = Instant::now();
let mut j: usize = 0;
loop {
if j == 1_000_000 { break; }
j = j + 1;
}
let t22: SystemTime = SystemTime::now();
let d: Thd = Thd01 {a: j, b: t21, c: t22, d:start_02.elapsed()};
let d2:(usize, SystemTime, SystemTime, core::time::Duration) = (d.a, d.b, d.c, d.d);
d2
});
}
}
fn main() {
// Error `так не работает`:
let handle: JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> = Thd::new();
let t11: SystemTime = SystemTime::now();
let start_01 = Instant::now();
let mut i: usize = 0;
loop {
if i == 1_000_000 { break; }
i = i + 1;
}
let t12 = SystemTime::now();
let d2 = handle.join().expect("thread panicked :...");
println!("i = {:?} \nt11 = {:?} \nt12 = {:?}", i, t11, t12);
println!("dt_01 = {:?}\n", start_01.elapsed());
//
println!("j = {:?} \nt21 = {:?} \nt22 = {:?}", &d2.0, &d2.1, &d2.2);
println!("dt_02 = {:?}\n", &d2.3);
}
update_01
use std::time::{SystemTime, Instant};
use std::thread;
use thread::JoinHandle;
struct Thd {
a: usize,
b: SystemTime,
c: SystemTime,
dt: core::time::Duration,
}
impl Thd {
pub fn new() -> JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> {
let handle: JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> =
thread::spawn(|| {
let t21: SystemTime = SystemTime::now();
let start_02 = Instant::now();
let mut j: usize = 0;
loop {
if j == 1_000_000 { break; }
j = j + 1;
}
let t22: SystemTime = SystemTime::now();
let d: Thd = Thd {a: j, b: t21, c: t22, dt:start_02.elapsed()};
let d2:(usize, SystemTime, SystemTime, core::time::Duration) = (d.a, d.b, d.c, d.dt);
d2
});
handle
}
}
fn main() {
// `так работает`:
let handle: JoinHandle<(usize, SystemTime, SystemTime, core::time::Duration)> = Thd::new();
let t11: SystemTime = SystemTime::now();
let start_01 = Instant::now();
let mut i: usize = 0;
loop {
if i == 1_000_000 { break; }
i = i + 1;
}
let t12 = SystemTime::now();
let d2 = handle.join().expect("thread panicked :...");
println!("i = {:?} \nt11 = {:?} \nt12 = {:?}", i, t11, t12);
println!("dt_01 = {:?}\n", start_01.elapsed());
//
println!("j = {:?} \nt21 = {:?} \nt22 = {:?}", &d2.0, &d2.1, &d2.2);
println!("dt_02 = {:?}\n", &d2.3);
}
/*
i = 1000000
t11 = SystemTime { tv_sec: 1737389697, tv_nsec: 383198522 }
t12 = SystemTime { tv_sec: 1737389697, tv_nsec: 385890160 }
dt_01 = 2.931694ms
j = 1000000
t21 = SystemTime { tv_sec: 1737389697, tv_nsec: 383252593 }
t22 = SystemTime { tv_sec: 1737389697, tv_nsec: 386045474 }
dt_02 = 2.792891ms
*/
Ответы (1 шт):
Автор решения: extrn
→ Ссылка
Хочу из main для потока в impl задавать количество итераций
Внесите, пожалуйста, ответ
С учетом того, что Thd
это все-таки не сам тред, а результат его работы, тем более, что использоваться он может и без создания треда, есть смысл вообще исключить упоминание тредов из имплементации, а также переименовать его, ну и немного обобщить.
use std::fmt;
use std::thread;
use std::time::{Duration, Instant, SystemTime};
#[derive(Debug)]
pub struct Metrics<T> {
result: T,
start: SystemTime,
stop: SystemTime,
elapsed: Duration,
}
impl<T> Metrics<T> {
pub fn gather(f: impl FnOnce() -> T) -> Self {
let start = SystemTime::now();
let instant = Instant::now();
let result = f();
let stop = SystemTime::now();
let elapsed = instant.elapsed();
Self { result, start, stop, elapsed }
}
}
impl<T: fmt::Display> fmt::Display for Metrics<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "result = {}", self.result)?;
writeln!(f, "start = {:?}", self.start)?;
writeln!(f, "stop = {:?}", self.stop)?;
writeln!(f, "elapsed = {:?}", self.elapsed)?;
Ok(())
}
}
fn main() {
fn work() -> Metrics<usize> {
Metrics::gather(|| {
let mut i: usize = 0;
loop {
if i == 1_000_000 { break; }
i = i + 1;
}
i
})
}
let handle = thread::spawn(work);
let result1 = work();
let result2 = handle.join().unwrap();
println!("main\n{result1}");
println!("spawned\n{result2}");
}
main
result = 1000000
start = SystemTime { tv_sec: 1737472310, tv_nsec: 712452124 }
stop = SystemTime { tv_sec: 1737472310, tv_nsec: 714353146 }
elapsed = 1.900872ms
spawned
result = 1000000
start = SystemTime { tv_sec: 1737472310, tv_nsec: 712530206 }
stop = SystemTime { tv_sec: 1737472310, tv_nsec: 714439057 }
elapsed = 1.908791ms