본문 바로가기

Rust

(18)
러스트 뮤텍스와 세마포어 1. 뮤텍스는 단일 자원을 보호하는데 사용 이때 단점은 다른 스레드 자원해제 될 때까지 무한히 대기하는 상황이 발생해 DeadLock이 발생한다. (정보처리기사 실기 운영체제 파트 공부를 하면서 나온내용이다!!!) use std::thread; use std::sync::Mutex; // counter를 전역변수로 지정 static counter: Mutex = Mutex::new(0); // counter에 접근할 때 뮤텍스로 잠금해서 상호베제를 한다. fn inc_counter() { let mut num = counter.lock().unwrap(); *num = *num +1; } fn main(){ // 스레드를 저장할 벡터 생성 let mut thread_vec = vec![]; for _ i..
Bufreader read_line()으로 파일 한줄씩 읽고 바이트 반환, Cursor 로 Read 구현 1. 데이터를 효율적으로 읽을 때 버퍼링을 사용한다. 이 때 Bufreader의 메서드 read_line()을 쓰면 한줄씩 데이터를 읽어오고 바이트를 반환해준다. (주석 설명 참고)use std::io::prelude::*; use std::io::BufReader; use std::fs::File; fn main() -> std::io::Result{ let s = File::open("tests/inputs/test.txt")?; // 버퍼 인스턴스 생성 let mut reader = BufReader::new(s); // String 타입 인스턴스 생성 let mut line = String::new(); // read_line은 한줄을 읽고 바이트를 반환한다. let len = reader.rea..
러스트로 리눅스 wc명령어 구현 wc명령어는 줄,단어, 바이트 수를 알려주는 기본 명령어이다 1. 파생패턴을 이용해 명령줄 인수를 파싱을 한다. // 파생패턴 #[derive(Debug,Parser)] #[command(author,version,about)] struct Args{ #[arg(value_name="FILE", default_value="-")] // 연속된 문자열은 연속된 배열인 벡터에 담긴다 files:Vec, // 줄수 #[arg(short,long)] lines:bool, // 단어 수 #[arg(short,long)] words:bool, // 바이트 수 #[arg(short('c'),long)] bytes:bool, // 문자 수 #[arg(short('m'),long, conflicts_with("bytes..
Rust 아토믹(atomic)연산 스레드 아토믹 연산자를 사용하면 여러 스레드가 안전하게 동일한 변수를 읽고 변경할 수 있다. Ordering::Relaxed는 순서 제한은 없으며 원자적 작업만 가능하다. while인자에 load메서드로 감싼 some_work메서드는 Relaxed의 영향을 받는다 (load메서드는 아토믹 변수에 저장된 값을 읽는다 즉 Relaxed로 설정한 인자 값을 읽는다) store 메서드 인자에 Relaxed의 논리값을 true로 설정해서 load메서드를 통해 읽어들어서 백그라운드 스레드가 실행되어break 명령을 만날때까지 스레드가 계속 실행된다(store메서드는 값을 수정하더라도 독자적 참조가 아닌 공유참조를 사용한다.) 종료프로그램 코드예시use std::sync::atomic::AtomicBool; use std:..
Rust 스레드 파킹 파킹을 사용하여 잠금을 하고 해제할 수 도 있다. 스레드 park()는 잠금, unpark() 잠금해제이다. 예를 들어 큐가 비어 있으면 스레드를 잠금하고 다른 곳에서 스레드를 잠금해제하여 깨워서 1초동안 0부터 시작하여 값을 호출한다.use std::collections::VecDeque; use std::sync::Mutex; use std::thread; use std::time::Duration; fn main() { let queue = Mutex::new(VecDeque::::new()); thread::scope(|s|{ let t = s.spawn(|| loop { let item = queue.lock().unwrap().pop_front(); if let Some(item) = item..
Rust 스레드 조건 변수 대기와 알림 조건변수(condition variable)를 사용해 데이터에 어떤일이 발생할 때 까지 대기했다가 알림 메서드를 호출하여 하나 또는 모든 대기스레드를 깨울 수 있다. 예를 들어 데이터를 추가 할 때 조건변수를 사용하여 데이터가 비어 있으면 값을 추가하고 데이터가 비어 있지 않으면 wait함수를 사용해 기다렸다가 notify_one 메서드를 사용해 하나의 메서드를 깨워서 비어있지 않고 데이터 값이 있다고 알림을 해준다.use std::collections::VecDeque; use std::sync::Condvar; use std::sync::Mutex; use std::thread; use std::time::Duration; fn main() { let queue = Mutex::new(VecDeque..
타입 가드 타입가드: 변수의 타입을 더 구체적이게 좁혀나간다. 참고자료 https://doc.rust-lang.org/std/sync/struct.Mutex.htmlMutex in std::sync - RustCalls U::from(self). That is, this conversion is whatever the implementation of From for U chooses to do.doc.rust-lang.org
Rust Mutex 스레드 Arc 스마트포인터는 참조 카운터를 변경하는 타입이고 병렬처리에서 스레드 간 금액 데이터를 안전하게 공유할 수 있다. Mutex 스레드를 사용해 스레드를 잠금했다. 잠긴 스레드에 데이터를 엑세스 하고 싶으면 lock메서드를 사용하여 잠금을 풀 수 있다. 그리고 Mutex는 여러스레드가 동시에 데이터에 엑세스 할 수 없다. 예제에서는 금액인출에 대해 트랜잭션 ACID를 구현해 보았다.use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; fn alarm(balance: Arc, amount: i32) { // Arc를 통해 금액 데이터를 안전하게 공유한다 // lock 메서드를 사용해 데이터 엑세스 허용 let mut balance =..