C 다중 스레딩 및 동시성 : 병렬 프로그래밍 마스터 링
C 멀티 스레딩 및 동시 프로그래밍의 핵심 개념에는 스레드 생성 및 관리, 동기화 및 상호 제외, 조건부 변수, 스레드 풀링, 비동기 프로그래밍, 일반적인 오류 및 디버깅 기술, 성능 최적화 및 모범 사례가 포함됩니다. 1) std :: 스레드 클래스를 사용하여 스레드를 만듭니다. 예제는 스레드가 완성 될 때까지 생성하고 기다리는 방법을 보여줍니다. 2) std :: mutex 및 std :: lock_guard를 사용하여 공유 리소스를 보호하고 데이터 경쟁을 피하기 위해 동기화 및 상호 배제. 3) 조건 변수는 std :: 조건 _variable을 통한 스레드 간의 통신과 동기화를 실현합니다. 4) 스레드 풀 예제는 ThreadPool 클래스를 사용하여 효율성을 향상시키기 위해 작업을 병렬로 처리하는 방법을 보여줍니다. 5) 비동기 프로그래밍은 std :: async 및 std :: future를 사용하여 구현됩니다. 이 예제는 비동기 작업의 시작 및 결과 획득을 보여줍니다. 6) 일반적인 오류에는 데이터 경쟁, 교착 상태 및 자원 누출, 디버깅 기술, 잠금 및 원자 운영 사용 및 디버깅 도구가 포함됩니다. 7) 성능 최적화 제안에는 스레드 풀의 사용, std :: Atomic 및 합리적인 자물쇠 사용, 프로그램 성능 및 보안을 개선하는 것이 포함됩니다.
소개
현대 프로그래밍에서 멀티 스레딩 및 동시 프로그래밍은 프로그램 성능과 대응 성을 향상시키는 핵심 기술이되었습니다. 고성능 컴퓨팅 애플리케이션을 개발하든 반응 형 사용자 인터페이스를 구축하든 C에서 멀티 스레딩 및 동시 프로그래밍 마스터 링은 필수적인 기술입니다. 이 기사는 C 멀티 스레딩 및 동시 프로그래밍의 핵심 개념과 실용적인 기술을 깊이 이해하여 병렬 프로그래밍의 마스터가 될 수 있도록합니다.
이 기사를 읽으면 스레드를 만들고 관리하는 방법을 배우고 동시 프로그래밍에서 동기화 및 상호 배제 메커니즘을 이해하고 일반적인 동시 프로그래밍 함정을 피하는 방법을 배웁니다. 초보자이든 숙련 된 개발자이든 이익을 얻을 수 있습니다.
기본 지식 검토
C Multithreading 및 동시 프로그래밍으로 다이빙하기 전에 먼저 몇 가지 기본 사항을 검토해 봅시다. C 11 표준은 <thread></thread>
라이브러리를 소개하여 C에서 스레드를 만들고 관리하는 것이 더 쉽고 직관적입니다. 또한 <mutex></mutex>
, <condition_variable></condition_variable>
및 <atomic></atomic>
과 같은 라이브러리는 스레드 간의 동기화 및 통신을 처리하는 데 필요한 도구를 제공합니다.
이러한 기본 개념을 이해하는 것은 멀티 스레드 프로그래밍을 마스터하는 데 중요합니다. 예를 들어, 스레드는 가장 작은 운영 체제 스케줄링 단위이며, 뮤 테스는 공유 리소스를 보호하고 데이터 경쟁을 방지하는 데 사용됩니다.
핵심 개념 또는 기능 분석
스레드 생성 및 관리
C에서 스레드를 만드는 것은 매우 간단합니다. std::thread
클래스를 사용하십시오. 간단한 예는 다음과 같습니다.
#include <iostream> #Include <streld> void strand_function () { std :: cout << "Hello From Thread!" << std :: endl; } int main () { std :: thread t (thread_function); t.join (); 반환 0; }
이 예제는 스레드를 생성하고 완료되기를 기다리는 방법을 보여줍니다. join()
메소드는 자식 스레드가 실행을 완료 할 때까지 메인 스레드를 차단합니다.
동기화 및 상호 배제
멀티 스레드 프로그래밍에서는 데이터 경쟁을 피하는 데 동기화 및 상호 배제가 핵심입니다. std::mutex
및 std::lock_guard
는 일반적으로 사용되는 도구입니다. 다음은 공유 리소스를 보호하기 위해 MUTEX를 사용하는 예입니다.
#include <iostream> #Include <streld> #include <MUTEX> std :: mutex mtx; int shared_data = 0; 무효 증분 () { for (int i = 0; i <100000; i) { std :: lock_guard <std :: mutex> 잠금 (mtx); shared_data; } } int main () { std :: 스레드 t1 (증분); std :: 스레드 t2 (증분); t1.join (); t2.join (); std :: cout << "shared_data의 최종 값 :"<< shared_data << std :: endl; 반환 0; }
이 예에서 std::lock_guard
데이터 경쟁을 피하고 shared_data
에 액세스 할 때 Mutex가 올바르게 잠금 및 잠금 해제되도록합니다.
조건부 변수
조건 변수는 스레드 간의 통신에 사용되는 또 다른 중요한 동기화 메커니즘입니다. 조건부 변수를 사용하는 예는 다음과 같습니다.
#include <iostream> #Include <streld> #include <MUTEX> #include <컨디션_variable> std :: mutex mtx; std :: 조건 _variable cv; bool ready = false; void print_id (int id) { std :: 고유 한 <std :: mutex> lck (mtx); while (! ready) cv.Wait (LCK); std :: cout << "스레드"<< id << std :: endl; } void go () { std :: 고유 한 <std :: mutex> lck (mtx); ready = true; cv.notify_all (); } int main () { STD :: 스레드 스레드 [10]; for (int i = 0; i <10; i) { 스레드 [i] = std :: 스레드 (print_id, i); } std :: cout << "레이스 준비가 된 10 개의 스레드 ..."<< std :: endl; 가다(); for (auto & th : streads) th.join (); 반환 0; }
이 예에서 조건 변수 cv
모든 대기 스레드에 실행을 시작하도록 알리는 데 사용됩니다.
사용의 예
기본 사용
스레드 생성 및 관리는 다중 스레드 프로그래밍의 기초입니다. 다음은 스레드 풀을 사용하여 작업을 병렬로 처리하는 방법을 보여주는보다 복잡한 예입니다.
#include <iostream> #include <vector> #Include <streld> #include <queue> #include <MUTEX> #include <컨디션_variable> #include <functional> 클래스 스레드 풀 { 공공의: ThreadPool (size_t 스레드) : stop (false) { for (size_t i = 0; i <스레드; i) { workers.emplace_back ([this] { while (true) { std :: function <void ()> 작업; { std :: 고유 한 <std :: mutex> lock (queue_mutex); 조건. WAIT (잠금, [this] {return stop ||! tasks.empty ();}); if (stop && tasks.empty ()) 반환; task = std :: move (tasks.front ()); tasks.pop (); } 일(); } }); } } 템플릿 <클래스 F, 클래스 ... Args> 자동 enqueue (f && f, args && ... args) -> std :: future <typename std :: result_of <f (args ...)> :: type> { return_type = typename std :: result_of <f (args ...)> :: type; auto task = std :: make_shared <std :: packaged_task <return_type () >> std :: bind (std :: forward <f> (f), std :: forward <Args> (args) ...) ); std :: future <return_type> res = task-> get_future (); { std :: 고유 한 <std :: mutex> lock (queue_mutex); if (stop) std :: runtime_error를 던지십시오 ( "정지 된 스레드 풀의 enqueue"); tasks.emplace ([task] () {(*task) ();}); } 조건 .notify_one (); 리턴 레스; } ~ ThreadPool () { { std :: 고유 한 <std :: mutex> lock (queue_mutex); 정지 = 참; } 조건 .notify_all (); for (std :: Thread & Worker : Workers) Worker.join (); } 사적인: std :: vector <std :: 스레드> 작업자; std :: queue <std :: function <void () >> 작업; std :: mutex queue_mutex; std :: 조건 _variable 조건; 부리 정지; }; int main () { 스레드 풀 풀 (4); std :: vector <std :: future <int >> 결과; for (int i = 0; i <8; i) { results.emplace_back ( pool.enqueue ([i] { 반환 i * i; }) ); } for (auto && result : results) { std :: cout << result.get () << ''; } std :: cout << std :: endl; 반환 0; }
이 예제는 스레드 풀을 사용하여 작업을 병렬로 처리하여 프로그램 동시성 및 효율성을 향상시키는 방법을 보여줍니다.
고급 사용
실제 애플리케이션에서는보다 복잡한 동시 프로그래밍 시나리오가 발생할 수 있습니다. 예를 들어, std::async
및 std::future
사용하여 비동기 프로그래밍을 구현합니다.
#include <iostream> #include <future> #include <Chrono> int main () { Auto Future = std :: async (std :: launk :: async, [] { std :: this_thread :: sleep_for (std :: chrono :: seconds (2)); 반환 42; }); std :: cout << "결과를 기다리고 있습니다 ..."<< std :: endl; int result = future.get (); std :: cout << "결과 :"<< 결과 << std :: endl; 반환 0; }
이 예에서 std::async
비동기 작업을 시작하는 데 사용되며 std::future
작업 결과를 얻는 데 사용됩니다.
일반적인 오류 및 디버깅 팁
멀티 스레드 프로그래밍의 일반적인 오류에는 데이터 레이스, 교착 상태 및 자원 누출이 포함됩니다. 디버깅 팁은 다음과 같습니다.
-
std::lock_guard
및std::unique_lock
사용하여 뮤트를 올바르게 사용하고 교착 상태를 피하십시오. -
std::atomic
사용하여 공유 변수를 처리하고 데이터 경쟁을 피하십시오. - Memory Leaks 및 Data Competition을 감지하기 위해 Valgrind 또는 AddressSanitizer와 같은 디버깅 도구를 사용하십시오.
성능 최적화 및 모범 사례
실제 응용 분야에서는 다중 스레드 프로그램의 성능을 최적화하는 것이 중요합니다. 다음은 몇 가지 최적화 팁과 모범 사례입니다.
- 과도한 실 생성 및 파괴를 피하고 스레드 풀을 사용하여 스레드를 관리하십시오.
-
std::atomic
사용하여 공유 변수의 액세스 효율성을 향상시킵니다. - 자물쇠를 합리적으로 사용하여 자물쇠의 세분성을 줄이고 잠금 경쟁을 피하십시오.
예를 들어 다음은 std::atomic
사용하여 공유 변수에 대한 액세스를 최적화하는 예입니다.
#include <iostream> #Include <streld> #include <Atomic> std :: atomic <int> shared_data (0); 무효 증분 () { for (int i = 0; i <100000; i) { shared_data; } } int main () { std :: 스레드 t1 (증분); std :: 스레드 t2 (증분); t1.join (); t2.join (); std :: cout << "shared_data의 최종 값 :"<< shared_data << std :: endl; 반환 0; }
이 예에서는 std::atomic
사용하여 공유 변수의 원자 운영이 프로그램 성능과 보안을 향상시킵니다.
요컨대, C 멀티 스레딩 및 동시 프로그래밍은 복잡하지만 매우 유용한 기술입니다. 이 기사의 연구를 통해 스레드 작성 및 관리, 동기화 및 상호 배제, 성능 최적화와 같은 핵심 개념 및 기술을 마스터해야합니다. 이 지식이 실제 프로젝트에 다중 스레드 프로그래밍을 더 잘 적용하고 프로그램 성능 및 대응 성을 향상시키는 데 도움이되기를 바랍니다.
위 내용은 C 다중 스레딩 및 동시성 : 병렬 프로그래밍 마스터 링의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











C++ 동시 프로그래밍에서는 데이터 구조의 동시성이 안전한 설계가 중요합니다. 중요 섹션: 뮤텍스 잠금을 사용하여 동시에 하나의 스레드만 실행할 수 있는 코드 블록을 만듭니다. 읽기-쓰기 잠금: 여러 스레드가 동시에 읽을 수 있지만 동시에 쓸 수 있는 스레드는 하나만 허용됩니다. 잠금 없는 데이터 구조: 원자 연산을 사용하여 잠금 없이 동시성 안전성을 달성합니다. 실제 사례: 스레드로부터 안전한 큐: 임계 섹션을 사용하여 큐 작업을 보호하고 스레드 안전성을 달성합니다.

작업 예약 및 스레드 풀 관리는 C++ 동시 프로그래밍의 효율성과 확장성을 향상시키는 핵심입니다. 작업 예약: std::thread를 사용하여 새 스레드를 만듭니다. 스레드를 조인하려면 Join() 메소드를 사용하십시오. 스레드 풀 관리: ThreadPool 개체를 생성하고 스레드 수를 지정합니다. 작업을 추가하려면 add_task() 메서드를 사용하세요. 스레드 풀을 닫으려면 Join() 또는 stop() 메서드를 호출하십시오.

동시 프로그래밍의 이벤트 중심 메커니즘은 이벤트가 발생할 때 콜백 함수를 실행하여 외부 이벤트에 응답합니다. C++에서는 이벤트 기반 메커니즘을 함수 포인터로 구현할 수 있습니다. 함수 포인터는 이벤트가 발생할 때 실행될 콜백 함수를 등록할 수 있습니다. 람다 표현식은 이벤트 콜백을 구현하여 익명 함수 객체를 생성할 수도 있습니다. 실제 사례에서는 함수 포인터를 사용하여 GUI 버튼 클릭 이벤트를 구현하고, 콜백 함수를 호출하고 이벤트가 발생할 때 메시지를 인쇄합니다.

C++의 스레드 간 통신 방법에는 공유 메모리, 동기화 메커니즘(뮤텍스 잠금, 조건 변수), 파이프 및 메시지 대기열이 포함됩니다. 예를 들어, 공유 카운터를 보호하기 위해 뮤텍스 잠금을 사용합니다. 뮤텍스 잠금(m)과 공유 변수(카운터)를 선언합니다. 각 스레드는 잠금(lock_guard)을 통해 카운터를 업데이트합니다. 경쟁 조건을 방지하기 위해.

스레드 부족을 방지하려면 공정한 잠금을 사용하여 리소스를 공정하게 할당하거나 스레드 우선순위를 설정할 수 있습니다. 우선순위 역전 문제를 해결하려면 리소스를 보유한 스레드의 우선순위를 일시적으로 높이는 우선순위 상속을 사용하거나 리소스가 필요한 스레드의 우선순위를 높이는 잠금 승격을 사용할 수 있습니다.

C++ 다중 스레드 프로그래밍에서 동기화 프리미티브의 역할은 공유 리소스에 액세스하는 여러 스레드의 정확성을 보장하는 것입니다. 여기에는 다음이 포함됩니다. Mutex(Mutex): 공유 리소스를 보호하고 동시 액세스를 방지합니다. 조건 변수(ConditionVariable): 스레드 특정 대기 실행을 계속하기 전에 충족해야 할 조건: 작업이 중단 없이 실행되는지 확인합니다.

C++의 스레드 종료 및 취소 메커니즘은 다음과 같습니다. 스레드 종료: std::thread::join()은 대상 스레드가 실행을 완료할 때까지 현재 스레드를 차단합니다. std::thread::detach()는 스레드 관리에서 대상 스레드를 분리합니다. 스레드 취소: std::thread::request_termination()은 대상 스레드에 실행을 종료하도록 요청합니다. std::thread::get_id()는 대상 스레드 ID를 획득하고 std::terminate()와 함께 사용하여 대상을 즉시 종료할 수 있습니다. 실. 실제 전투에서 request_termination()은 스레드가 종료 시점을 결정하도록 허용하고, Join()은 이를 메인 라인에서 보장합니다.

C++ 동시 프로그래밍 프레임워크는 다음과 같은 옵션을 제공합니다: 경량 스레드(std::thread), 스레드로부터 안전한 Boost 동시성 컨테이너 및 알고리즘, 고성능 ThreadBuildingBlocks(TBB) (cpp-동의).
