[c++] C++ 스레드 풀과 스레드 풀 공유 리소스 관리

이 블로그 포스트에서는 C++로 스레드 풀을 구현하고, 스레드 풀에서 공유하는 리소스를 안전하게 관리하는 방법에 대해 알아보겠습니다.

C++ 스레드 풀 구현하기

스레드 풀은 일정한 개수의 스레드를 미리 생성해두고, 작업이 들어오면 해당 스레드들에게 작업을 분배하는 방식으로 동작합니다. C++에서는 이를 std::threadstd::mutex를 사용하여 구현할 수 있습니다.

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

class ThreadPool {
public:
    ThreadPool(size_t threadCount) : stop(false) {
        for (size_t i = 0; i < threadCount; ++i) {
            threads.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queueMutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty()) {
                            return;
                        }
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    template<class F>
    void enqueue(F&& f) {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            tasks.emplace(std::forward<F>(f));
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread &worker : threads) {
            worker.join();
        }
    }

private:
    std::vector<std::thread> threads;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
};

위 코드는 C++11에서 동작하는 간단한 스레드 풀을 보여줍니다. enqueue 함수를 통해 작업을 스레드 풀에 추가하고, 소멸자를 통해 스레드 풀을 안전하게 종료합니다.

스레드 풀에서 공유 리소스 관리하기

스레드 풀에서는 여러 스레드가 공유 리소스에 접근하므로, 이를 안전하게 관리해야 합니다. C++에서는 std::mutex 및 다른 동기화 메커니즘을 사용하여 공유 리소스에 대한 접근을 제어할 수 있습니다.

예를 들어, 아래는 스레드 풀에서 공유하는 std::vector를 안전하게 관리하는 예시입니다.

class SharedResource {
public:
    void addData(int data) {
        std::lock_guard<std::mutex> lock(mutex);
        sharedData.push_back(data);
    }

    void printData() {
        std::lock_guard<std::mutex> lock(mutex);
        for (const auto& data : sharedData) {
            std::cout << data << " ";
        }
        std::cout << std::endl;
    }

private:
    std::vector<int> sharedData;
    std::mutex mutex;
};

위 코드에서 addDataprintData 함수는 std::mutex를 사용하여 공유 리소스에 안전하게 접근합니다.

이처럼 C++에서는 스레드 풀을 구현하고, 스레드 풀에서 공유하는 리소스를 안전하게 관리할 수 있습니다.

이상으로 C++ 스레드 풀과 스레드 풀에서 공유 리소스를 관리하는 방법에 대해 알아보았습니다. 안전한 다중 스레드 환경을 구현하기 위해서는 항상 동기화 메커니즘을 적절히 활용하는 것이 중요합니다.

참고문헌:

관련 참고 자료:

기술 블로그 작성 예시입니다.