Threads Simples

Threads em Rust funcionam de maneira semelhante às threads em outras linguagens:

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

fn main() {
    thread::spawn(|| {
        for i in 1..10 {
            println!("Contagem na _thread_: {i}!");
            thread::sleep(Duration::from_millis(5));
        }
    });

    for i in 1..5 {
        println!("_Thread_ principal: {i}");
        thread::sleep(Duration::from_millis(5));
    }
}
  • Threads são todas “daemon threads”, a thread principal não espera por elas.
  • Panics” em threads são independentes uns dos outros.
    • Panics” podem carregar um payload (carga útil), que pode ser descompactado com downcast_ref.
This slide should take about 15 minutes.
  • As APIs de threads do Rust não parecem muito diferentes das de C++.

  • Execute o exemplo.

    • O tempo de 5ms é suficientemente folgado para que a thread principal e as threads filhas permaneçam principalmente em sincronia.
    • Observe que o programa termina antes que a thread filha alcance 10!
    • Isso ocorre porque o main termina o programa e as threads filhas não o mantêm.
      • Compare com pthreads/C++ std::thread/boost::thread se desejar.
  • Como esperamos a thread filha terminar?

  • thread::spawn retorna um JoinHandle. Veja a documentação.

    • JoinHandle tem um método .join() bloqueante.
  • Use let handle = thread::spawn(...) e depois handle.join() para esperar que a thread termine e fazer o programa contar até 10.

  • Agora, e se quisermos retornar um valor?

  • Olhe a documentação novamente:

  • Use o valor de retorno Result de handle.join() para obter acesso ao valor retornado.

  • Ok, e quanto ao outro caso?

    • Dispare um panic na thread. Observe como isso não afeta main.
    • Acessa o payload do panic. Este é um bom momento para falar sobre Any.
  • Agora podemos retornar valores de threads! E quanto a receber entradas?

    • Capture algo por referência no encerramento da thread.
    • Uma mensagem de erro indica que devemos movê-lo.
    • Mova-o, veja que podemos calcular e depois retornar um valor derivado.
  • E se quisermos emprestar?

    • O main mata as threads filhas quando retorna, mas outra função apenas retornaria e as deixaria em execução.
    • Isso seria acesso após retorno da pilha, o que viola a segurança de memória!
    • Como evitamos isso? Veja o próximo slide.