ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++ 멀티스레딩 프로그래밍과 동기화 기법
    c++ 2025. 2. 3. 21:10
    728x90

    1. 멀티스레딩(Multithreading)이란?

    멀티스레딩은 하나의 프로그램이 동시에 여러 작업을 수행할 수 있게 해주는 기술입니다. C++에서는 thread 라이브러리를 통해 멀티스레딩을 구현할 수 있습니다.

    (1) 스레드의 기본 개념

    • 스레드(Thread): 프로세스 내에서 실행되는 가장 작은 단위
    • 멀티스레딩을 통해 병렬 처리가 가능하여 성능을 향상시킬 수 있습니다.

    2. C++에서 스레드 사용하기

    (1) 기본 스레드 생성 및 실행

    #include <iostream>
    #include <thread>
    using namespace std;
    
    void printMessage() {
        cout << "스레드에서 실행 중입니다." << endl;
    }
    
    int main() {
        // 스레드 생성
        thread t(printMessage);
    
        // 메인 스레드에서 실행
        cout << "메인 스레드에서 실행 중입니다." << endl;
    
        // 스레드 종료 대기
        t.join();
    
        return 0;
    }

    출력 결과:

    메인 스레드에서 실행 중입니다.
    스레드에서 실행 중입니다.

    (2) 인자 전달 스레드

    스레드 함수에 인자를 전달할 수 있습니다.

    #include <iostream>
    #include <thread>
    using namespace std;
    
    void printNumber(int num) {
        cout << "숫자: " << num << endl;
    }
    
    int main() {
        thread t(printNumber, 42);
        t.join();
        return 0;
    }

    출력 결과:

    숫자: 42

    3. 동기화(Synchronization)란?

    동기화는 여러 스레드가 공유 자원에 동시에 접근할 때 발생할 수 있는 문제(데이터 충돌)를 방지하기 위한 기술입니다.

    (1) 데이터 경쟁(Race Condition)

    • 두 개 이상의 스레드가 동일한 자원에 접근할 때 발생하는 예측 불가능한 결과
    • 이를 방지하기 위해 **뮤텍스(Mutex)**를 사용합니다.

    4. 뮤텍스(Mutex) 사용하기

    (1) 기본 뮤텍스 사용법

    #include <iostream>
    #include <thread>
    #include <mutex>
    using namespace std;
    
    mutex mtx;  // 뮤텍스 객체 생성
    
    void printSafeMessage(const string& message) {
        mtx.lock();
        cout << message << endl;
        mtx.unlock();
    }
    
    int main() {
        thread t1(printSafeMessage, "스레드 1 실행 중");
        thread t2(printSafeMessage, "스레드 2 실행 중");
    
        t1.join();
        t2.join();
    
        return 0;
    }

    출력 결과:

    스레드 1 실행 중
    스레드 2 실행 중

    (2) lock_guard를 활용한 뮤텍스 관리

    lock_guard는 뮤텍스를 자동으로 관리하여 lockunlock을 명시적으로 작성할 필요가 없습니다.

    #include <iostream>
    #include <thread>
    #include <mutex>
    using namespace std;
    
    mutex mtx;
    
    void printSafeMessage(const string& message) {
        lock_guard<mutex> lock(mtx);  // 자동으로 뮤텍스 잠금 및 해제
        cout << message << endl;
    }
    
    int main() {
        thread t1(printSafeMessage, "스레드 1 실행 중");
        thread t2(printSafeMessage, "스레드 2 실행 중");
    
        t1.join();
        t2.join();
    
        return 0;
    }

    5. 조건 변수(Condition Variable)

    조건 변수는 스레드 간의 통신을 가능하게 하며, 특정 조건이 충족될 때까지 스레드를 대기 상태로 유지합니다.

    (1) 조건 변수 사용 예제

    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <condition_variable>
    using namespace std;
    
    mutex mtx;
    condition_variable cv;
    bool ready = false;
    
    void printMessage() {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock, [] { return ready; });  // ready가 true가 될 때까지 대기
        cout << "스레드가 실행되었습니다." << endl;
    }
    
    int main() {
        thread t(printMessage);
    
        this_thread::sleep_for(chrono::seconds(2));  // 2초 대기
        {
            lock_guard<mutex> lock(mtx);
            ready = true;
        }
        cv.notify_one();  // 대기 중인 스레드 깨우기
    
        t.join();
        return 0;
    }

    출력 결과:

    스레드가 실행되었습니다.

    6. 멀티스레딩 실전 예제: 병렬 합계 계산

    멀티스레딩을 활용하여 배열의 합계를 병렬로 계산하는 예제입니다.

    #include <iostream>
    #include <vector>
    #include <thread>
    using namespace std;
    
    void partialSum(const vector<int>& data, int start, int end, int& result) {
        result = 0;
        for (int i = start; i < end; ++i) {
            result += data[i];
        }
    }
    
    int main() {
        vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int result1 = 0, result2 = 0;
    
        // 두 개의 스레드를 사용하여 배열을 나누어 합계 계산
        thread t1(partialSum, cref(data), 0, data.size() / 2, ref(result1));
        thread t2(partialSum, cref(data), data.size() / 2, data.size(), ref(result2));
    
        t1.join();
        t2.join();
    
        cout << "총 합계: " << result1 + result2 << endl;
        return 0;
    }

    출력 결과:

    총 합계: 55

     

    728x90
Designed by Tistory.