2015-01-28 2 views
0

У меня есть функция C, которая для разных причин C может быть вызвана только из определенных видов потоков. Я пытаюсь вызвать эту функцию из Rust.Данные о доставке в и за закрытие

Идея, что я должен был отправить входные данные в «правый» поток, вызвать функцию C в этом потоке, а затем дождаться потока, используя семафор, прежде чем отправить возвращаемое значение обратно.

Нить не используется для параллелизма; это действительно довольно синхронный поток выполнения. Это просто, что функция C не знает, как ее можно использовать.

Это была моя попытка:

use std::thread::Thread; 

struct Foo { 
    x: std::sync::Semaphore, 
} 

//Not the real C function, of course. 
fn my_great_c_function(i: i32) -> i32 { 
    println!("{}",i); 
    return 12; 
} 

impl Foo { 
    fn bar(&self) { 
     self.x = std::sync::Semaphore::new(0); 
     let input : i32 = 5; 
     let mut output : i32 = 10; 
     Thread::spawn(|:| { 
      //call out to our C function that only likes some threads 
      output = my_great_c_function(input); 
      self.x.release(); //our work is done; the parent thread can continue 
     }); 
     self.x.acquire(); //wait for child thread to be done interacting with environment 
     println!("{}",input); //check input 
     println!("{}",output); //check output 
    } 

} 

Компилятор Rust выводит целую страницу ошибок, объясняя, что ему cannot infer an appropriate lifetime due to conflicting requirements.

Из того, что я могу кусочки, я думаю, что компилятор обеспокоен тем, что крышка может пережить кадр стека, а также ссылки закупоривающих к input и output могут сломаться во время закрытия все еще использовать их (это, я подозреваю, , значение lifetime parameter must outlive the static lifetime). Но на самом деле семафор используется для сохранения кадра стека до тех пор, пока закрытие не завершится, так что этого не должно произойти.

Есть ли способ успокоить компилятор? Есть ли другой способ решить эту проблему?

ответ

1

Thread::spawn определяется следующим образом:

fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static 

Функция вы передаете он должен иметь все свои данные ('static этого требует). Вы, однако, пытаетесь что-то сделать с self, который определенно не 'static. Помните, Rust заботится о безопасности; потокам не разрешается связываться с данными других потоков: вы не можете получить доступ к объекту более чем в одном потоке.

То, что вы хотите на самом деле проще, чем то, что вы пытаетесь: использовать Thread::scoped:

impl Foo { 
    fn bar(&self) { 
     let input = 5i32; 
     let output = Thread::scoped(|:| { 
      my_great_c_function(input) 
     }).join().unwrap(); 
     println!("{}", input); 
     println!("{}", output); 
    } 
} 
+0

Я попробовал это, но я получил 'ядро :: Результат :: Результат > 'не реализует никакого метода в области с именем' unwrap'. Я попытался использовать .ok(). Вместо этого распакуйте() и получите больше 'не может вывести соответствующий срок службы из-за противоречивых требований.' – Drew

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