Search

Race condition 발생 예제

Race Condition 발생 시

Race condition은 여러 개의 스레드가 동시에 동일한 자원에 접근할 때 발생할 수 있는 문제입니다. Rust는 안전한 병렬 처리를 위한 메커니즘을 제공하며, 이를 활용하면 race condition 문제를 방지할 수 있습니다. 그러나 안전한 병렬 처리를 위해서는 일부 코드 수정이 필요할 수 있습니다.
다음은 race condition을 유발할 수 있는 예제입니다. 이 코드는 std::thread를 사용하여 두 개의 스레드를 생성하고, 스레드에서 동시에 변수를 수정하려고 시도합니다.
use std::thread; fn main() { let mut count = 0; let t1 = thread::spawn(|| { for _ in 0..10_000 { count += 1; } }); let t2 = thread::spawn(|| { for _ in 0..10_000 { count += 1; } }); t1.join().unwrap(); t2.join().unwrap(); println!("Count: {}", count); }
Rust
복사
위 코드는 두 개의 스레드가 각각 count 변수를 10,000번씩 증가시키려고 시도합니다. 그러나 이 코드는 race condition을 유발할 수 있습니다. count 변수는 둘 이상의 스레드에서 동시에 수정할 수 있으므로, 두 스레드가 동시에 count 변수에 접근하여 증가시키려고 할 때, 예기치 않은 결과가 발생할 수 있습니다.
이 코드에서는 안전한 병렬 처리를 위한 동기화 메커니즘이 적용되지 않았으므로, count 변수를 안전하게 수정할 수 없습니다. 이러한 문제를 해결하기 위해서는 Mutex나 Atomic 변수를 사용하여 동기화하는 등의 방법이 있습니다. 이를 통해 race condition을 방지할 수 있습니다.

Race Condition 해소 방법

위에서 제시한 race condition을 해결하기 위해서는 스레드 간 동기화 메커니즘이 필요합니다. Rust에서는 Mutex나 Atomic 변수를 사용하여 스레드 간 동기화를 할 수 있습니다.
아래는 Mutex를 사용하여 race condition을 해결하는 예제입니다.
use std::sync::{Arc, Mutex}; use std::thread; fn main() { let count = Arc::new(Mutex::new(0)); let mut threads = Vec::new(); for _ in 0..2 { let count = Arc::clone(&count); let t = thread::spawn(move || { for _ in 0..10_000 { let mut val = count.lock().unwrap(); *val += 1; } }); threads.push(t); } for t in threads { t.join().unwrap(); } println!("Count: {}", *count.lock().unwrap()); }
Rust
복사
위 코드에서는 ArcMutex를 사용하여 count 변수를 안전하게 스레드 간 공유합니다. Arc는 여러 스레드에서 공유할 수 있는 스마트 포인터이며, Mutex는 데이터의 상호 배제를 위해 사용됩니다.
스레드에서 count 변수를 증가시키기 전에 count.lock().unwrap()를 호출하여 뮤텍스를 잠그고(lock()) 가져옵니다. 이를 통해 한 번에 하나의 스레드만 count 변수에 접근할 수 있습니다. 스레드에서 작업을 마치면, Mutex를 자동으로 해제하며(unlock()) 다른 스레드가 count 변수에 접근할 수 있도록 합니다.
따라서 위 코드를 실행하면 race condition이 발생하지 않고, 정확한 결과가 출력됩니다.

컬렉션 찾아보기

시리즈