[c++] C++ 스레드 풀과 동적 스레드 생성

스레드는 병렬 처리를 위해 사용되며, C++11 이후부터 표준 라이브러리에 std::thread 클래스가 추가되었습니다. 스레드를 관리하기 위해 스레드 풀을 사용할 수 있으며, 이를 통해 스레드의 동적 생성 및 관리가 가능해집니다.

스레드 풀이란?

스레드 풀은 미리 정해진 개수의 스레드를 생성하고 이를 관리하는 기법입니다. 이를 통해 스레드 생성과 소멸에 따르는 오버헤드를 줄일 수 있습니다. 또한, 작업을 처리하기 위해 기다리는 스레드를 재활용하여 성능을 향상시킬 수 있습니다.

C++에서 스레드 풀 사용하기

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

class ThreadPool {
public:
    ThreadPool(size_t numThreads) : _stop(false) {
        for (size_t i = 0; i < numThreads; ++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;
};

int main() {
    ThreadPool pool(4);
    pool.enqueue([] {
        std::this_thread::sleep_for(std::chrono::seconds(3));
        std::cout << "Task 1" << std::endl;
    });
    pool.enqueue([] {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "Task 2" << std::endl;
    });
    return 0;
}

위의 코드는 C++을 사용하여 간단한 스레드 풀을 구현한 예시입니다. ThreadPool 클래스를 통해 원하는 개수의 스레드를 생성하고, enqueue 함수를 통해 작업을 스레드 풀에 추가할 수 있습니다.

스레드 풀은 std::thread를 직접 생성하고 관리하는 것보다 편리하며, 성능 및 자원 관리 측면에서도 유리할 수 있습니다.

마무리

스레드 풀을 사용하면 스레드의 동적 생성 및 관리를 편리하게 할 수 있습니다. 이를 통해 병렬 처리가 필요한 프로그램에서 성능 향상과 자원 효율성을 높일 수 있습니다.

참고문헌: