2016-08-14 5 views
2

:보낼 수 없습니다 A & STR이 살고 있지 않기 때문에 스레드 사이에 다음과 같은 간단한 프로그램을 감안할 때 충분히

#[macro_use] extern crate log; 
extern crate ansi_term; 
extern crate fern; 
extern crate time; 
extern crate threadpool; 
extern crate id3; 

mod logging; 

use std::process::{exit, }; 
use ansi_term::Colour::{Yellow, Green}; 
use threadpool::ThreadPool; 
use std::sync::mpsc::channel; 
use std::path::{Path}; 
use id3::Tag; 

fn main() { 
    logging::setup_logging(); 

    let n_jobs = 2; 

    let files = vec!(
     "/tmp/The Dynamics - Version Excursions/01-13- Move on Up.mp3", 
     "/tmp/The Dynamics - Version Excursions/01-09- Whole Lotta Love.mp3", 
     "/tmp/The Dynamics - Version Excursions/01-10- Feel Like Making Love.mp3" 
    ); 
    let pool = ThreadPool::new(n_jobs); 
    let (tx, rx) = channel(); 
    let mut counter = 0; 

    for file_ in files { 
     let file_ = Path::new(file_); 
     counter = counter + 1; 
     let tx = tx.clone(); 

     pool.execute(move || { 
      debug!("sending {} from thread", Yellow.paint(counter.to_string())); 

      let tag = Tag::read_from_path(file_).unwrap(); 
      let a_name = tag.artist().unwrap(); 

      debug!("recursed file from: {} {}", 
        Green.paint(a_name), file_.display()); 

      tx.send(".").unwrap(); 
      // TODO amb: not working.. 
      // tx.send(a_name).unwrap(); 
     }); 
    } 

    for value in rx.iter().take(counter) { 
     debug!("receiving {} from thread", Green.paint(value)); 
    } 
    exit(0); 
} 

모두가 하나가 라인 (tx.send(a_name).unwrap();)에 다시 넣어 댓글을 달았하지 않는 한, 예상대로 작동한다는 점에서.

error: `tag` does not live long enough 
      let a_name = tag.artist().unwrap(); 
         ^~~ 
    note: reference must be valid for the static lifetime... 
note: ...but borrowed value is only valid for the block suffix following statement 1 at 39:58 
      let tag = Tag::read_from_path(file_).unwrap(); 
      let a_name = tag.artist().unwrap(); 

      debug!("recursed file from: {} {}", 
        Green.paint(a_name), file_.display()); 

... 

은 일반적으로 내가 컴파일러가 내게 말하길 이해,하지만 난 폐쇄 블록의 내부에 정의 된 변수 tag 때문에 문제가 표시되지 않습니다 경우 나는 다음과 같은 오류가 발생합니다. 내가 추측 할 수있는 유일한 문제는 변수 tx이 외부에 clone d이므로 tag의 유효 기간과 충돌 할 수 있다는 것입니다.

내 목표는 스레드 내부의 스레드 클로저에 모든 현재 논리를 두는 것입니다.이 스레드는 여러 스레드로 확산되기를 원하는 "처리"이기 때문입니다. 이를 어떻게 수행 할 수 있습니까? 그러나 기존의 tx에 더 오래 가치를 보내시겠습니까? 나는 다음과 같은 녹 버전을 사용하고

:

$ rustc --version 
rustc 1.9.0 (e4e8b6668 2016-05-18) 
$ cargo --version 
cargo 0.10.0-nightly (10ddd7d 2016-04-08) 

답변

3

a_nametag에서 차용 &str입니다. 따라서 그 수명은 tag으로 제한됩니다. 기타 'static 참조가 아닌 채널을 다른 스레드로 보내는 것은 안전하지 않습니다. 수신자가 액세스하려고하면 더 이상 존재하지 않을 수도있는 스레드 스택의 내용을 참조합니다. 귀하의 경우 a_name을 수신자 스레드로 이동되는 String 유형의 소유 값으로 승격시켜야합니다.

tx.send(a_name.to_owned()).unwrap();