After reading Rust book chapter 16

rust


코드를 동시에 실행하기 위해 스레드 사용하기


spawn: 스레드 생성하기

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

fn main() {
    thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }
}


join: 모든 스레드 끝나도록 기다리기

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

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    // (1)
    // handle.join().unwrap();

    for i in 1..5 {
        println!("hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }

    // (2)
    handle.join().unwrap();
}
// (1) 결과
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
// (2) 결과
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 1 from the spawned thread!
hi number 3 from the main thread!
hi number 2 from the spawned thread!
hi number 4 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!


move Closures: 다른 스레드로 소유권 이동하기

use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(|| {
        println!("Here's a vector: {:?}", v);
    });

    // (1)
    // drop(v)

    handle.join().unwrap();
}


use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    });

    // (1)
    // drop(v)

    handle.join().unwrap();
}



멀티 스레드 사용하기

메시지 패싱

채널


채널 생성

use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();
}


채널을 통해 메시지 주고받기

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });

    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}


채널과 소유권 이전

fn main() {
    thread::spawn(move || {
        let val = String::from("hi");

				// 소유권 넘어감
        tx.send(val).unwrap();

				// Error: borrow of moved value: `val`
        println!("val is {}", val);
    });
}


Multiple Producer

fn main() {
    let (tx, rx) = mpsc::channel();
    let tx1 = tx.clone();
}


상태 공유

뮤텍스


Mutex

use std::sync::Mutex;

fn main() {
		// 초기값 5
    let m = Mutex::new(5);

    {
        let mut num = m.lock().unwrap();

				// 값을 6으로 변경
        *num = 6;
    }

    println!("m = {:?}", m);
}


Arc - Mutex 공유하기


use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();

            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}


Send & Sync



Rust의 멀티쓰레드는 언제나 안전한 걸까?