- Rust는 가비지 컬렉션을 사용하지 않고 소유권, 차용, 수명을 통해 컴파일 시 메모리 안전성을 보장합니다.
- 유형 시스템과 별칭 규칙은 뮤텍스, 채널, 스마트 포인터를 사용하여 데이터 경쟁 없이 동시성을 허용합니다.
- Cargo, crates.io 및 활성 생태계는 종속성 관리, 컴파일, 테스트 및 배포를 간소화합니다.
- 구조체, 열거형, 옵션, 결과를 이해하는 것은 동시 애플리케이션에서 오류를 처리하고 안전한 데이터를 모델링하는 데 중요합니다.
Rust는 그러한 언어 중 하나가 되었습니다. 모든 시스템 개발자는 이 말을 계속해서 듣게 됩니다.C나 C++만큼 빠르지만, 메모리 안전성과 잘 실행되는 동시성에 거의 집착할 정도로 집중합니다. 이는 단순한 마케팅이 아닙니다. 컴파일러가 컴파일 타임에 오류를 감지하도록 설계되었으며, 다른 언어에서는 시스템이 이미 운영 중이거나 충돌할 때만 이러한 오류가 발생합니다.
이해에 관심이 있다면 Rust가 가비지 수집 없이 안전한 메모리를 구현하고 데이터 실행에 대한 두려움 없이 동시성을 구현하는 방법이 튜토리얼은 여러분을 위한 것입니다. 언어와 생태계의 기본부터 소유권, 차용, 복합 타입, Cargo와 같은 도구와 같은 핵심 개념까지 모든 것을 다루고, 동시성을 처음 접하는 사람들을 위해 더 이해하기 쉬운 관점에서 원자 타입과 잠금까지 살펴봅니다. 이 모든 과정은 보안과 성능에 중점을 두고 진행됩니다.
Rust 튜토리얼: 성능, 메모리 안전 및 동시성
Rust는 프로그래밍 언어입니다 프로그래밍 일반 용도 및 다중 패러다임용으로 설계되었습니다. 저수준 시스템 프로그래밍뿐만 아니라 고수준 프로젝트도 가능,에서 운영 체제게임 엔진과 브라우저부터 고성능 웹 서비스에 이르기까지, 이는 특히 브라우저 엔진과 같은 민감한 구성 요소의 소프트웨어 보안을 개선한다는 목표로 Mozilla에서 시작되었습니다.
그 정의적 특징은 다음과 같습니다. 컴파일 시간에 메모리 안전성을 보장합니다. 가비지 컬렉터를 사용하지 않습니다. 대신 Rust는 소유권 시스템과 각 값과 참조의 수명을 추적하는 빌림 검사기를 사용합니다. 이를 통해 자동 참조 카운팅이나 가비지 컬렉터를 사용하지 않고도 댕글링 포인터, 버퍼 오버플로, 메모리 누수와 같은 고전적인 문제를 방지합니다.
또한 Rust는 더 쉽게 만들도록 설계되었습니다. 안전한 동시성이 함수의 타입 및 소유권 모델은 스레드 간 데이터 경쟁을 방지하며, 적어도 안전한 Rust 코드에서는 그렇습니다. 즉, 단 한 줄도 실행되기 전에 컴파일 타임에 많은 위험한 상황이 감지된다는 것을 의미합니다.
이러한 모든 이유로 대기업은 Dropbox, Microsoft, Amazon 또는 구글 그들은 인프라의 핵심 부분에 Rust를 도입했습니다. Rust가 개발자들이 "가장 사랑받는" 언어 중 하나로 Stack Overflow에서 수년간 1위를 차지한 것은 우연이 아닙니다. Rust는 C++ 스타일의 성능과 현대적인 툴셋(Cargo, crates.io), 그리고 소위 Rustaceans이라 불리는 매우 활동적인 커뮤니티를 결합했습니다.
기본 개념: 프로그래밍 언어, 유형 및 메모리
메모리 보안 및 동시성의 세부 사항을 살펴보기 전에 이 문서 전반에 나타나는 몇 가지 일반적인 개념을 명확히 하는 것이 좋습니다. 시간 Rust로 작업할 때, 특히 다른 언어를 사용하거나 프로그래밍을 막 시작하는 경우.
프로그래밍 언어는 궁극적으로 알고리즘을 설명할 수 있는 규칙과 구조 세트 이를 실행 가능한 프로그램으로 변환합니다. Rust는 자체 컴파일러를 사용하여 네이티브 기계어 코드로 컴파일합니다. rustc따라서 얻는 성능은 일반적으로 C 및 C++와 동일합니다.
메모리 관리란 프로그램이 수행하는 프로세스입니다. 실행 중 메모리 블록을 예약하고 해제합니다.이 영역에서 발생하는 오류는 종종 치명적입니다. 메모리 누수(사용되지 않는 메모리를 해제하지 못함), 범위를 벗어난 쓰기로 인한 데이터 손상, 해제된 메모리를 다시 사용하는 등의 오류가 발생할 수 있습니다. Rust는 매우 강력한 타입 시스템과 소유권, 차용, 그리고 수명에 대한 공식적인 규칙을 통해 이러한 문제를 해결합니다.
Rust에는 다음과 같은 용어도 있습니다. 스마트 유형 및 포인터유형은 변수가 어떤 종류의 데이터를 저장하는지(정수, 실수, 문자열, 구조체 등)와 어떻게 조작할 수 있는지를 설명합니다. 스마트 포인터(예: Box, Rc y Arc)은 메모리 주소를 캡슐화하고 공유 참조를 계산하거나 값을 힙으로 이동하는 등 리소스를 안전하게 관리하기 위한 추가 논리를 추가하는 구조입니다.
경쟁 분야에서는 다음과 같은 개념이 있습니다. 경쟁 조건, 뮤텍스 및 채널 이러한 기능은 필수적입니다. 여러 스레드가 적절한 조정 없이 동시에 공유 리소스에 액세스하고 수정할 경우 경쟁 조건이 발생하고, 뮤텍스(상호 배제)는 한 번에 하나의 스레드만 중요 섹션에 들어가도록 보장하며, 채널을 사용하면 메모리를 직접 공유하지 않고도 스레드 간에 메시지를 보낼 수 있습니다.
Rust를 배우는 이유: 메모리 안전성과 두려움 없는 동시성
Rust는 다음과 같은 이유로 명성을 얻었습니다. 현대 프로그래밍을 위한 세 가지 매우 귀중한 기둥성능, 보안, 그리고 최신 도구들. 이러한 점들이 왜 중요한지 살펴보겠습니다.
성능과 관련하여 Rust 네이티브 바이너리로 직접 컴파일 가상 머신이나 인터프리터가 필요 없습니다. 무비용 추상화 모델은 고수준 추상화가 런타임에 오버헤드를 발생시키지 않도록 하는 것을 목표로 합니다. 따라서 시스템 개발에 이상적입니다. 경기, 브라우저 구성 요소 또는 저지연 마이크로서비스.
메모리 보안은 다음을 기반으로 합니다. 소유권 및 대출 시스템가비지 컬렉터는 없지만, 컴파일러는 각 리소스의 소유자가 누구인지, 언제 더 이상 필요하지 않은지, 언제 해제할 수 있는지 정확히 알고 있습니다. 이를 통해 누수, 댕글링 포인터, 그리고 전통적으로 C와 C++ 프로그래밍을 매우 위험하게 만들었던 여러 오류를 방지할 수 있습니다.
경쟁 분야에서 Rust는 일반적으로 다음과 같이 불리는 것을 추구합니다. “두려움 없는 동시성”타입 시스템 자체는 보안 코드에 데이터 루트가 존재하는 것을 방지합니다. 스레드 간에 변경 가능한 데이터를 공유하려면 다음과 같은 적절한 기본형을 사용해야 합니다. Mutex, RwLock o Arc컴파일러는 별칭 및 가변성 규칙이 준수되도록 보장합니다.
다음과 같은 최신 도구를 사용하면 개발 경험이 향상됩니다. 뱃짐통합 패키지 관리자와 빌드 인프라, 그리고 비동기 네트워킹(Tokyo)부터 웹 프레임워크(Actix, Rocket, Axum)까지 모든 것을 아우르는 광범위한 라이브러리(크레이트) 생태계를 갖추고 있습니다. 이 모든 것은 특히 초보자를 위한 개방적이고 활발하며 인내심이 강한 커뮤니티의 지원을 받습니다.
설치 및 필수 도구: rustup, rustc 및 Cargo
Rust에서 첫 번째 프로그램을 작성하고 실행하려면 일반적으로 공식 툴체인을 설치하여 시작합니다. 녹슬다 (참조 Rust에 대한 완전한 소개), 모든 주요 운영체제에서 작동하는 간단한 설치 프로그램 및 버전 관리자입니다.
와 녹슬다 Rust의 여러 버전(안정 버전, 베타 버전, 나이틀리 버전)을 설치, 업데이트하고 전환해도 아무런 문제 없이 사용할 수 있습니다. 공식 Rust 도구 페이지로 이동하여 시스템에 맞는 단계를 따르세요. 설치가 완료되면 컴파일러를 사용할 수 있습니다. rustc, 프로젝트 관리자 cargo 그리고 자신의 rustup 당신의 단말기.
컴파일러 rustc 소스 코드를 실행 가능한 바이너리나 라이브러리로 변환하는 역할을 합니다. 다음을 통해 직접 호출할 수도 있습니다. 명령 으로 rustc main.rs실제로는 거의 항상 Cargo를 통해 작업하게 되며, Cargo는 다음과 같은 호출을 처리합니다. rustc 적절한 옵션을 통해.
워크플로의 핵심 도구는 다음과 같습니다. 뱃짐몇 가지 명령만으로 crates.io에서 새 프로젝트를 생성하고, 종속성을 관리하고, 패키지를 컴파일, 실행, 테스트하고, 게시할 수 있습니다. 자주 사용되는 기본 명령은 다음과 같습니다. cargo new, cargo build, cargo run, cargo test y cargo check최종 실행 파일을 생성하지 않고 코드를 검사하는 방식으로, 오류를 빠르게 감지하는 데 이상적입니다.
아무것도 설치하지 않고 땜질하고 싶다면, 러스트 놀이터 (공식 온라인 실행기) 및 Replit과 같은 플랫폼을 사용하면 브라우저에서 작은 코드 조각을 작성하고 실행할 수 있으므로 전체 환경을 설정하지 않고도 메모리 및 동시성 예제를 실험하는 데 적합합니다.
첫 번째 프로그램: Hello, Rust 및 기본 흐름
어떤 언어로든 대화를 시작하는 고전적인 방법은 유명한 "Hello, world"를 사용하는 것입니다. Rust에서는 파일 main.rs 최소한 함수처럼 간단한 것을 포함할 수 있습니다. main 화면에 문자열을 출력합니다.
키워드 fn 우리가 함수를 정의하고 있음을 나타냅니다. main 이것이 프로그램의 진입점입니다. 함수의 코드 블록은 중괄호 안에 들어갑니다. 콘솔에 쓰려면 다음을 사용하세요. 매크로 println!문자열 리터럴(또는 북마크가 있는 템플릿)을 받아서 줄바꿈 문자로 끝나는 문자열을 표준 출력으로 보냅니다.
직접 컴파일하면 rustc main.rs, 실행 가능한 바이너리를 받게 됩니다(예: main o main.exe (시스템에 따라 다릅니다.) 실행하면 터미널에 메시지가 표시됩니다. 하지만 Rust를 사용하는 일반적인 방법은 Cargo가 프로젝트를 주도하도록 하는 것입니다.
와 cargo new nombre_proyecto 폴더 구조는 자동으로 생성됩니다. src/main.rs 이미 "Hello, world"와 파일이 준비되어 있습니다. Cargo.toml 여기에는 메타데이터와 향후 종속성이 포함됩니다. 여기에서 cargo run 바이너리를 컴파일하고 실행하세요그리고 변경 사항이 감지되면 다시 컴파일됩니다.
이런 작업 방식은 편리할 뿐만 아니라 처음부터 표준 Rust 생태계에 익숙해지는 데 도움이 되며, 동시성, 네트워킹, 테스트 등 필요한 작업을 위한 크레이트를 추가할 때 매우 유용합니다.
// main 함수를 선언합니다. 프로그램 진입점 fn main() { // println! 매크로를 사용하여 콘솔에 텍스트를 출력합니다. println!("Hello, world!"); }
변수, 가변성 및 기본 데이터 유형
Rust에서는 변수가 키워드로 선언됩니다. let, 그리고 기본적으로 그것들은 불변이다즉, 값을 할당한 후에는 명시적으로 변경 가능하다고 선언하지 않는 한 해당 값을 수정할 수 없습니다. mut.
기본적으로 불변성은 미묘한 논리 오류를 방지하는 데 도움이 됩니다. 특히 여러 스레드가 동일한 값을 변경하려는 동시 프로그램에서 더욱 그렇습니다. 값을 변경해야 하는 경우 다음과 같이 작성합니다. let mut contador = 0;거기에서 새로운 값을 다시 할당할 수 있습니다. contador.
Rust는 또한 소위 말하는 것을 허용합니다. 그림자동일한 범위 내에서 동일한 이름의 새 변수를 선언하고 이전 변수를 숨길 수 있습니다. 이는 새로운 값(다른 유형일 수도 있음)을 생성하기 때문에 변경과는 다릅니다. 예를 들어, 동일한 이름을 사용하여 문자열을 정수로 변환할 수 있습니다. 단, 다음과 같은 새 선언이어야 합니다. let.
Rust의 유형 시스템은 정적입니다. 즉, 각 변수의 유형은 컴파일 시에 알려집니다.그러나 유형 추론은 매우 강력합니다. 다음과 같이 작성하면 let x = 5;컴파일러는 그것이 다음과 같다고 가정합니다. i32 달리 명시하지 않는 한 다음과 같은 메모를 추가할 수 있습니다. let x: i64 = 5; 명확하게 표현하고 싶을 때.
사용 가능한 스칼라 유형에는 부호 있는 정수와 부호 없는 정수가 있습니다.i8, u8, i32, 등), 떠다니는 것들(f32, f64), 부울(bool) 및 유니코드 문자(char). 이러한 간단한 유형은 일반적으로 복사 비용이 저렴하며 많은 유형이 특성을 구현합니다. Copy즉, 함수에 할당하거나 전달하면 이동되지 않고 복사된다는 의미입니다.
Rust의 문자열: &str 및 String
Rust에서 텍스트 처리가 처음에는 약간 혼란스러울 수 있습니다. 왜냐하면 다음과 같은 차이점이 명확하게 구분되기 때문입니다. 체인 "슬라이스" 및 독점 체인두 가지 핵심 요소는 다음과 같습니다. &str y String.
Un &str 하는 변경 불가능한 체인의 조각어딘가에 저장된 UTF-8 바이트 시퀀스의 모습입니다. 일반적인 예로는 다음과 같은 리터럴이 있습니다. "Hola"어떤 유형인가 &'static str (이것은 프로그램의 전체 수명 동안 존재하며 바이너리에 내장되어 있습니다.) 슬라이스는 데이터를 소유하지 않으며, 단지 데이터를 가리킬 뿐입니다.
String반면에, 자체 문자열, 변경 가능하며 힙에 호스팅됨크기를 조절하거나, 연결하거나, 속성을 이동하여 함수 간에 전달하는 등의 작업이 가능합니다. 동적 텍스트를 작성하거나 구조체 내에서 장기간 저장하려는 경우에 자주 사용됩니다.
많은 시나리오에서 여러분은 하나에서 다른 하나로 변환할 것입니다: 예를 들어, 여러분은 다음을 만들 것입니다. String::from("hola") 한 조각에서아니면 빌릴 거야 &str 로 String 읽기만 하면 되는 함수에 대한 참조를 전달함으로써.
소유한 데이터와 빌린 데이터를 분리하는 것은 메모리 관리에 중요하며 언어의 나머지 부분에도 적용됩니다. 즉, 컬렉션, 구조체, 열거형은 누가 소유하고 누가 보기만 하는지에 대한 동일한 개념을 따릅니다.
함수, 제어 흐름 및 주석
Rust의 함수는 다음과 같이 정의됩니다. fn 그리고 프로그램을 재사용 가능한 논리적 단위로 구성할 수 있습니다. 각 함수는 다음을 지정합니다. 매개변수의 유형과 반환 유형 화살표를 따라가다 ->의미 있는 값을 반환하지 않으면 단일 유형으로 간주됩니다. ().
중요한 세부 사항은 세미콜론이 없는 함수(또는 블록)의 마지막 표현식이 암시적 반환 값으로 간주된다는 것입니다. 다음을 사용할 수 있습니다. return 조기 반품을 위해하지만 관용적인 코드에서는 종종 최종 표현식을 그대로 두는 경우가 많습니다. ;.
제어 흐름은 클래식으로 처리됩니다. if/else루프 loop, while y forRust에서는 if 값을 반환하는 표현식입니다그래서 당신은 그것을 직접 사용할 수 있습니다 let분기가 동일한 유형을 반환하는 경우 루프 for 일반적으로 범위나 컬렉션 반복자를 반복하며 수동 인덱스 대신 권장되는 옵션입니다.
코드를 문서화하고 이후의 사람(한 달 후의 본인 포함)의 삶을 더 편리하게 만들기 위해 다음을 사용할 수 있습니다. 줄 주석 // 또는 차단 /* ... */또한 Rust는 다음과 같은 문서 주석을 제공합니다. /// 생성된 문서가 되지만 이는 대규모 프로젝트에 더 적합합니다.
소유권, 대출 및 수명: 메모리 보안의 기초
여기서 우리는 Rust 메모리 모델의 핵심인 시스템에 도달합니다. 소유권, 차용 및 수명이러한 규칙은 참조가 항상 유효하고 메모리가 가비지 없이 안전하게 해제되도록 보장합니다.
소유권의 기본 규칙은 설명하기는 쉽지만, 처음에는 이해하기 어려울 수 있습니다. 각 값에는 단일 소유자가 있습니다.한 번에 소유자는 한 명만 있을 수 있으며, 소유자가 범위를 벗어나면 해당 값은 삭제되고 메모리가 해제됩니다. 이는 예를 들어 String: 선언된 블록이 완료되면 자동으로 호출됩니다. drop 그러면 힙 메모리가 해제됩니다.
다른 변수에 적절한 값을 할당하거나 함수에 값으로 전달하면 속성이 이동됩니다. 즉, 이동 후 원래 변수는 더 이상 유효하지 않습니다.이러한 이동 의미론은 두 명의 소유자가 동일한 리소스를 해제하려고 시도하는 일이 없기 때문에 이중 해제를 방지합니다.
프로그램의 여러 부분이 소유권을 변경하지 않고 동일한 값에 접근할 수 있도록 Rust는 참조와 차용을 도입했습니다. 차용을 통해 참조를 생성합니다. &T (변경 불가능) 또는 &mut T 소유권을 이전하지 않고 값으로 변경 가능합니다. 대출은 대출 검증자의 규칙에 따라 제한됩니다.참조가 가리키는 데이터보다 오래 지속되지 않는지, 변경 가능한 액세스와 공유 액세스가 위험할 정도로 혼합되지 않았는지 확인하는 기능입니다.
대출 규칙은 다음과 같이 요약할 수 있습니다. 언제든지 다음 중 하나를 선택할 수 있습니다. 여러 개의 변경 불가능한 참조 값으로, 또는 단일 변경 가능 참조하지만 동시에 두 가지를 동시에 실행할 수는 없습니다. 이렇게 하면 공유 메모리에서 경쟁 조건이 제거됩니다. 즉, 여러 개의 리더가 있거나, 하나의 쓰기만 있는 경우입니다. 즉, 같은 시점에 같은 데이터에 대해 리더와 쓰기가 동시에 발생하는 일이 없습니다.
복합 유형: 구조체, 열거형 및 스마트 포인터
Rust는 관련 데이터를 보다 풍부한 구조로 그룹화하는 여러 가지 방법을 제공합니다. 구조체구조체를 사용하면 이름이 지정된 필드가 있는 사용자 정의 유형을 정의할 수 있습니다. 예를 들어 이메일, 이름, 활동 상태 및 로그인 카운터가 있는 사용자입니다.
구조체의 인스턴스를 생성하려면 모든 필드를 채우고, 해당 인스턴스를 포함하는 변수를 변경 가능으로 표시하여 나중에 값을 수정할 수 있습니다. 또한, 기존 인스턴스의 일부 필드를 재사용하여 새 인스턴스를 만들 수 있는 구조체 업데이트 구문도 있습니다. ..otro_struct.
롯 열거형 또 다른 필수 요소입니다. 여러 가능한 변형 중 하나로 정의할 수 있는 유형을 정의할 수 있으며, 각 변형은 고유한 관련 데이터를 포함하거나 포함하지 않습니다. 대표적인 예로 IP 주소에 대한 열거형을 들 수 있는데, 여기에는 하나의 변형이 있습니다. V4 4개의 옥텟과 또 다른 옥텟을 저장합니다. V6 IPv6 표기법으로 문자열을 저장합니다.
Rust의 표준 라이브러리에는 두 가지 매우 중요한 열거형이 포함되어 있습니다. Option<T> y Result<T, E>첫 번째는 값의 존재 또는 부재(무언가 또는 아무것도 없음)를 나타내며 널 포인터를 피하는 데 사용됩니다. 두 번째는 다음과 같은 작업을 모델링합니다. 올바른 결과나 오류를 반환하다오류 처리가 명시적이고 안전해야 함을 요구합니다.
동적 메모리를 관리하고 데이터를 공유하기 위해 Rust는 스마트 포인터 으로 Box<T>값을 힙으로 옮기고 고유한 소유권을 유지합니다. Rc<T>, 단일 스레드 환경에 대한 공유 참조 횟수 및 Arc<T>, 비슷한 Rc 하지만 여러 스레드에서는 안전합니다. 동적 메모리와 동시성을 결합할 때 이를 올바르게 사용하는 것이 중요합니다.
화물과 상자 생태계
카고는 Rust 생태계를 하나로 묶어주는 접착제입니다. 컴파일, 종속성 및 프로젝트 수명 주기를 관리합니다.각 프로젝트에는 파일이 있습니다 Cargo.toml 이는 이름, 버전, 언어 버전 및 외부 종속성을 선언하는 매니페스트 역할을 합니다.
섹션 이 파일을 사용하면 타사 크레이트와 해당 버전을 나열할 수 있습니다. 다음을 실행하면 cargo build o cargo runCargo는 crates.io에서 이러한 크레이트를 자동으로 다운로드하고, 컴파일하여 프로젝트에 연결합니다. 예를 들어 난수 생성기, 웹 프레임워크, 암호화 라이브러리 등을 추가하는 것이 매우 쉽습니다.
가장 일반적인 명령은 다음과 같습니다. cargo new 바이너리 프로젝트를 시작하려면 o cargo new --lib 도서관을 위해; cargo build 디버그 모드에서 컴파일하려면; cargo build --release 최적화된 생산 지향 버전을 얻기 위해; cargo test 테스트를 실행하기 위해.
cargo check 특별히 언급할 가치가 있습니다. 바이너리를 생성하지 않고 코드를 중간 지점까지 컴파일하므로 컴파일 오류를 매우 빠르게 감지합니다대출 검사기가 속성, 참조 및 수명과 관련된 문제를 지적하는 동안 빠르게 반복하는 데 적합합니다.
이러한 생태계 덕분에 프로젝트를 작고 명확하게 정의된 크레이트로 구성하여 각 크레이트 간에 코드를 공유하고 커뮤니티에서 만든 솔루션을 재사용하는 것이 일반적입니다. 예를 들어 고급 동시성 기능을 위해서는 비동기 프로그래밍을 위한 Tokio 크레이트나 고성능 동시성 데이터 구조를 위한 Crossbeam 크레이트가 있습니다.
Rust의 동시성: 스레드, 뮤텍스, 채널 및 원자성
동시성은 Rust가 많은 관심을 받는 이유 중 하나입니다. 동시성을 통해 멀티코어 프로세서의 이점을 활용할 수 있습니다. 스레드와 공유 메모리의 일반적인 오류에 빠지지 않고이런 주제에 처음 접근하는 경우, 몇 가지 개념을 구별하는 것이 도움이 됩니다.
동시성은 하나 또는 여러 개의 코어에서 시간적으로 겹치는 여러 작업을 실행하는 것을 의미합니다. Rust에서는 시스템 스레드를 생성하여 병렬로 작업을 수행할 수 있으며, 언어는 스레드 간 데이터 공유가 안전하게 이루어지도록 지원합니다. 대표적인 오류는 경쟁 조건입니다. 두 스레드가 동시에 데이터에 접근하고 수정하는 경우, 그 결과는 실행 순서에 따라 달라지는데, 이는 디버깅하기가 매우 어렵습니다.
공유 데이터에 대한 액세스를 조정하기 위해 Rust는 다음과 같은 기본 요소를 사용합니다. 뮤텍스상호 배제를 보장하는 방식입니다. 한 번에 하나의 스레드만 임계 구역에 들어갈 수 있습니다. Arc<T> 스레드 간에 소유권을 공유하려면 소유권 및 차용 규칙을 준수하는 공유 데이터 구조를 구축할 수 있습니다.
Rust에서 강력히 권장하는 또 다른 일반적인 스레드 간 통신 형태는 메시지 전달입니다. 채널채널에는 송신측과 수신측이 있으며, 스레드는 이를 통해 메시지(값)를 전달하는데, 이를 통해 가변 공유 메모리의 사용이 줄어들고 시스템 상태에 대한 추론이 간소화됩니다.
저수준 동시성을 더 자세히 살펴보면 다음과 같은 내용이 나타납니다. 원자 유형원자 변수는 스레드 관점에서 분리할 수 없는 연산을 통해 접근합니다. 이를 통해 공유 카운터, 상태 플래그, 잠금 없는 큐 등을 구현할 수 있습니다. 원자 변수를 완벽하게 이해하려면 메모리 모델과 액세스 명령에 대한 이해가 필요하므로, 많은 개발자는 이러한 세부 사항을 살펴보기 전에 뮤텍스와 채널부터 시작하는 것을 선호합니다.
동시성과 원자성을 배우기 위한 첫 단계와 리소스
이전 경험 없이 경기장에 들어가는 경우 가장 현명한 행동 방침은 다음과 같습니다. 일반 개념의 탄탄한 기초를 쌓다 Rust의 원자 유형과 같은 고급 도구를 다루기 전에 먼저 이 부분을 다뤄야 합니다. "Programming Rust"와 같은 책은 점진적인 소개를 제공하지만, 원자 유형과 잠금에 초점을 맞춘 책들이 처음에는 어렵게 느껴지는 것은 당연합니다.
더 쉽게 사용하려면 먼저 다음 사항에 익숙해지는 것이 좋습니다. 전통적인 스레드, 상호 배제 및 메시지 전달 Rust에서. 예제를 사용해 보세요. std::thread, std::sync::Mutex, std::sync::Arc 및 채널 std::sync::mpsc 컴파일러가 어떻게 안내하는지, 어떤 오류를 방지하는지 이해하는 데 도움이 됩니다.
동시에 Rust에 초점을 맞추지 않았더라도 일반적인 동시성에 대한 입문 자료를 검토하는 것이 좋습니다. 경쟁 조건이 무엇인지, 블로킹이 무엇을 의미하는지, 공유 메모리가 메시지 전달과 어떤 관련이 있는지, 잠금이 어떻게 사용되는지 이해하는 것입니다. 일단 이러한 개념이 당신에게 자연스럽게 느껴지면, 원자 물리학은 더 이상 "흑마법"이 아닙니다. 그리고 그것들은 단지 또 다른 도구가 되며, 매우 섬세한 도구가 됩니다.
Rust에서 원자성과 잠금에 대한 고급 텍스트로 돌아갈 때, 각 구조가 해결하려는 문제가 무엇인지 이미 이해하고 있다면 추론을 따라가기가 훨씬 쉬울 것입니다. 간단한 스레드 안전 카운터부터 경합을 최소화하는 잠금 없는 구조까지 다양합니다.
궁극적으로 Rust는 고수준 기본 요소와 매우 저수준 도구를 모두 제공하며, 핵심은 항상 문제를 해결하는 가장 안전한 추상화 수준을 선택하고 원자 코드를 사용하는 것입니다. unsafe 그것이 정말로 가치를 더하고 그 의미를 완전히 이해할 때에만 가능합니다.
유형, 소유권, 차용, 상자, 도구 및 동시성 기본 요소의 전체 생태계가 결합되어 작성에 사용할 수 있는 언어를 제공합니다. 빠르고 견고하며 유지 관리가 가능한 소프트웨어이렇게 하면 역사적으로 시스템 프로그래밍을 괴롭혀 온 여러 유형의 오류를 최소화할 수 있습니다. 작은 프로젝트, Rustlings와 같은 연습, 그리고 공식 문서를 통해 연습하다 보면 이러한 개념들이 마치 엄격한 규칙처럼 느껴지던 것에서 벗어나 문제가 실제 운영 환경에 적용되기 전에 경고해 주는 든든한 동반자가 될 것입니다.
바이트와 기술 전반에 관한 세계에 대한 열정적인 작가입니다. 나는 글쓰기를 통해 내 지식을 공유하는 것을 좋아하며 이것이 바로 이 블로그에서 할 일이며 가젯, 소프트웨어, 하드웨어, 기술 동향 등에 관한 가장 흥미로운 모든 것을 보여 드리겠습니다. 제 목표는 여러분이 간단하고 재미있는 방식으로 디지털 세계를 탐색할 수 있도록 돕는 것입니다.