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
.
- "Panics" podem carregar um payload (carga Ăștil), que pode ser descompactado com
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 umJoinHandle
. Veja a documentação.JoinHandle
tem um método.join()
bloqueante.
-
Use
let handle = thread::spawn(...)
e depoishandle.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:
- O encerramento de
thread::spawn
retornaT
JoinHandle
.join()
retornathread::Result<T>
- O encerramento de
-
Use o valor de retorno
Result
dehandle.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
.
- Dispare um panic na thread. Observe como isso nĂŁo afeta
-
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.