[c++] C++에서의 스레딩 패턴

C++는 멀티스레딩을 지원하는 강력한 언어입니다. 이번 블로그 포스트에서는 C++에서 스레딩을 다루는 유용한 패턴에 대해 알아보겠습니다.

1. 분할 정복

분할 정복은 큰 작업을 작은 작업으로 나누어 각각의 작업을 병렬로 처리하는 기법입니다. C++에서는 std::asyncstd::future를 사용하여 이러한 패턴을 쉽게 구현할 수 있습니다.

아래는 분할 정복을 이용한 스레딩 코드의 간단한 예시입니다.

#include <iostream>
#include <future>
#include <vector>

int calculate(int value) {
    // 계산 작업
    return value * 2;
}

int main() {
    std::vector<std::future<int>> results;

    for (int i = 0; i < 10; ++i) {
        results.push_back(std::async(calculate, i));
    }

    for (int i = 0; i < 10; ++i) {
        std::cout << results[i].get() << std::endl;
    }

    return 0;
}

2. 생산자-소비자

생산자-소비자 패턴은 공유된 큐나 버퍼를 통해 작업을 공유하는 패턴입니다. C++에서는 이를 std::mutexstd::condition_variable을 이용하여 구현할 수 있습니다.

아래는 생산자-소비자 패턴을 이용한 스레딩 코드의 간단한 예시입니다.

#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

std::queue<int> dataQueue;
std::mutex dataMutex;
std::condition_variable dataCond;

void producer() {
    for (int i = 0; i < 10; ++i) {
        std::unique_lock<std::mutex> lock(dataMutex);
        dataQueue.push(i);
        lock.unlock();
        dataCond.notify_one();
    }
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(dataMutex);
        dataCond.wait(lock, [] { return !dataQueue.empty(); });
        int data = dataQueue.front();
        dataQueue.pop();
        lock.unlock();
        // data 처리
    }
}

int main() {
    std::thread producerThread(producer);
    std::thread consumerThread(consumer);

    producerThread.join();
    consumerThread.join();

    return 0;
}

결론

C++에서의 스레딩 패턴은 다양하고 유용합니다. 분할 정복과 생산자-소비자 패턴은 병렬 처리와 작업 관리에 있어 매우 효과적입니다. 이러한 패턴들을 적절히 활용하여 프로그램을 효율적으로 개발할 수 있습니다.

참고문헌: