2016-05-03 4 views

ответ

7

Вы можете использовать timer клеть

extern crate timer; 
extern crate chrono; 

use timer::Timer; 
use chrono::Duration; 
use std::thread; 

fn x() { 
    println!("hello"); 
} 

fn main() { 
    let timer = Timer::new(); 
    let guard = timer.schedule_repeating(Duration::seconds(2), x); 
    // give some time so we can see hello printed 
    // you can execute any code here 
    thread::sleep(::std::time::Duration::new(10, 0)); 
    // stop repeating 
    drop(guard); 
} 
+0

Не могли бы вы использовать это, чтобы обновить поле в изменяемой структуре? – lsund

+0

@lsund Если вы имеете в виду, можно ли оставить изменяемую ссылку в закрытии, доступной из другого места, из источника ящика, похоже, что ответ «нет» запрещает «Mutex''d» или «Arc» и т. Д. . ref к глобальному (или небезопасному) коду 'Cell'-and-friends. – user

+0

(а затем есть [каналы] (https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html) и [scoped_tls] (https://github.com/alexcrichton/scoped -tls/blob/master/src/lib.rs) и т. д., но в конце вам все равно нужно обернуть объект в путь 'Send'-ly. – user

5

Это достаточно легко написать подобную версию самостоятельно, используя только инструменты из стандартной библиотеки:

use std::thread; 
use std::time::Duration; 

struct Timer<F> { 
    delay: Duration, 
    action: F, 
} 

impl<F> Timer<F> 
where 
    F: FnOnce() + Send + Sync + 'static, 
{ 
    fn new(delay: Duration, action: F) -> Self { 
     Timer { delay, action } 
    } 

    fn start(self) { 
     thread::spawn(move || { 
      thread::sleep(self.delay); 
      (self.action)(); 
     }); 
    } 
} 

fn main() { 
    fn x() { 
     println!("hello"); 
     let t = Timer::new(Duration::from_secs(2), x); 
     t.start(); 
    } 

    let t = Timer::new(Duration::from_secs(2), x); 
    t.start(); 

    // Wait for output 
    thread::sleep(Duration::from_secs(10)); 
} 

Как pointed out by malbarbo, это создать новый THRE объявление для каждого таймера. Это может быть дороже решения, которое повторно использует потоки, но это очень простой пример.

+1

Обратите внимание, что это может быть неэффективно для выделения нового потока в каждый вызов 'start'. – malbarbo

+0

@malbarbo большой пункт! Если вы хотите выполнить повторяющуюся задачу, вам будет гораздо лучше использовать один и тот же поток снова и снова, и я предполагаю, что таймер с вашего ответа будет выполнен. Я просто пытался сопоставить семантику Python. – Shepmaster

Смежные вопросы