2016-05-25 7 views
0

In meinem Projekt brauche ich etwas zu tun:Wie emimiere ich einen Timer in einem Objekt, das das Objekt periodisch mutiert?

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

struct A { 
    pub ints: Vec<u8>, 
} 

impl A { 
    fn new() -> A { 
     let mut a = A { 
      ints: vec![1, 5, 6, 2, 3, 4], 
     }; 
     a.timer(); 
     a 
    } 

    fn timer(&mut self) { 
     thread::spawn(move || { 
      loop { 
       thread::sleep(Duration::from_millis(1)); 
       self.ints.remove(0); 
      } 
     }); 
    } 
} 

fn main() { 
    let a = A::new(); 
    loop { 
     println!("Remaining elements: {:?}", a.ints); 
    } 
} 

Die Idee ist, dass einige struct einen Vektor der Elemente enthält. Diese Elemente sollten nach einiger Zeit aus dem Vektor entfernt werden. Stellen Sie sich einen periodischen Timer vor, der etwas überprüft und eine Aktion an einem veränderbaren Objekt ausführt (entfernt ein Element). Dieser Thread muss auch gelöscht werden, wenn das Objekt, an dem gerade gearbeitet wird, gelöscht wird. Ich denke, es sollte ein Mitglied einer Struktur sein, die manipuliert wird.

Das Problem mit dem Code oben ist, dass es eine Menge borrow Fehler hat, und ich verstehe nicht, wie das zu tun.

Ich habe wie dieses paar Fragen gesehen, aber jeder von ihnen war Skalar in einem Thread zu manipulieren. Der Grund, warum ich kann es hier nicht anwenden, weil der Faden etwas sein soll, die innerhalbA Struktur ist und es soll remove auf einem Vektor nennen, der ein Mitglied dieser Struktur ist.

Ich glaube, ich Arc oder etwas ähnliches verwenden soll, aber nicht wirklich verstehen, wie es hier zu verwenden.

Antwort

2

Ich denke, ich sollte Arc oder etwas ähnliches verwenden, aber verstehe nicht wirklich, wie man es hier benutzt.

der Tat, dass die einfachste Lösung:

Sie können wickeln Sie das ints Feld in einem Arc, aber dann würden Sie nicht in der Lage sein, die Vec zu ändern, so dass Sie es auch wickeln in ein Mutex:

struct A { 
    pub ints: Arc<Mutex<Vec<u8>>>, 
} 

Dann können Sie die Arc klonen, um einen zweiten Griff zum gleichen Speicher zu erhalten.

fn timer(&mut self) { 
    let ints = self.ints.clone(); 
    thread::spawn(move || { 
     loop { 
      thread::sleep(Duration::from_millis(1)); 

Anstatt die Vec zugreifen, müssen Sie dann die Mutexlock, die fehlschlagen kann, wenn ein anderer Thread, während die Mutex Zugriff in Panik geraten.

  ints.lock().unwrap().remove(0); 
     } 
    }); 
} 
+0

Noch eine Frage - wird dieser erzeugte Thread automatisch gelöscht, wenn die Lebenszeit eines 'A'-Objekts beendet ist? –

+1

nein, dieser Thread läuft für immer, bis er in Panik gerät. Wenn Sie möchten, dass es zusammen mit 'A' gelöscht wird, müssen Sie das' JoinHandle' speichern, das von der Funktion 'spawn' im Objekt zurückgegeben wird, und' Drop' für 'A' implementieren und' join' auf dem Handle aufrufen. –

+0

Hier ist auch eine Frage - wie kann ich die Objekte in einem solchen Vektor ändern? Zum Beispiel, wenn es ein Vektor einer Struktur ist, inkrementiere ein Feld innerhalb dieser Struktur? Alle Möglichkeiten, die ich ausprobiert habe, haben Fehler bezüglich "kann nicht ausgeliehenen Inhalt ausziehen" oder "das Merkmal' core :: iter :: Iterator "ist nicht implementiert für den Typ" & std :: sync :: mutex :: MutexGuard <' _, Sammlungen :: vec :: Vec > '". Nehmen wir 'Player' als eine Struktur an, die ein Feld hat, das ich in diesem Thread ändern muss. –

Verwandte Themen