Rust로 병렬 처리하는 유파를 구현해 보자.

9018 단어 재료Rust

전 자료



@Nemesis 님의 Java에서 유파를 구현해보십시오. 에 편승해 보았습니다.

한가로이 쓰는 동안 앞을 넘어섰다.



Rust에서 유파를 구현해보십시오.

하지만 모처럼이기 때문에 투고해 버린다.

코드


use std::sync::{Arc, Mutex, Barrier};
use std::thread;
use rand::Rng;

fn main() {
    let mut handles = Vec::with_capacity(3);
    let name = Arc::new(Mutex::new(String::new()));
    let barrier = Arc::new(Barrier::new(3));

    handles.push(thread::spawn({
        let name = name.clone();
        let barrier = barrier.clone();
        move || {
            {
                let stdin = std::io::stdin();
                let mut locked = name.lock().unwrap();
                println!("湯婆婆A:契約書だよ。そこに名前を書きな。");
                let _ = stdin.read_line(&mut *locked);
            }
            barrier.wait();
        }
    }));

    handles.push(thread::spawn({
        let name = name.clone();
        let barrier = barrier.clone();
        move || {
            barrier.wait();
            let mut locked = name.lock().unwrap();
            println!("湯婆婆B:フン。{}というのかい。贅沢な名だねぇ。", locked.trim());
            let n = rand::thread_rng().gen_range(0, locked.trim().chars().count());
            *locked = locked.trim().chars().nth(n).unwrap().to_string();
        }
    }));

    handles.push(thread::spawn({
        let name = name.clone();
        let barrier = barrier.clone();
        move || {
            barrier.wait();
            println!("湯婆婆C:今からお前の名前は{0}だ。いいかい、{0}だよ。分かったら返事をするんだ、{0}!!", name.lock().unwrap().trim());
        }
    }));

    handles.into_iter().for_each(|h| { let _ = h.join(); });
}

포이즌 유파



빈 상태로 두면 한 스레드가 Mutex를 잠긴 상태로 종료되므로 유파 C는 포이즌 오류가 발생합니다. 포이즌 유파.



물론 유파 할머니 B는 충돌 유행 할 수 있습니다.

연대감



가끔 유파 C가 나옵니다.


결론



Rust는 병렬 처리를 비교적 기분 좋게 합니다.

하지만 역시 병렬 처리의 기본적인 생각을 소홀히 하고 있으면, 디버그하기 어려워지거나, 실행 타이밍이 관리할 수 없게 되거나 합니다.

그럼에도 불구하고 Rust는 병렬 처리를 작성하기 쉽습니다.

메모리 경합을 억제하기 위한 Mutex 이나 타이밍을 맞추기 위한 barrier , 디버그에 관해서는 std::io::Errornew 쪽이 좋은 생각은 하지만..).

Rust는 좋다. 특히 C++를 배운 분에게는 추천합니다. C++ 경험자라면 순조롭게 익숙해질 것입니다.

좋은 웹페이지 즐겨찾기