[c++] C++ 스레드 풀과 작업 로딩 밸런싱
이번 글에서는 C++을 사용하여 스레드 풀을 구현하고, 작업 로딩 밸런싱을 적용하는 방법에 대해 알아보겠습니다.
스레드 풀 구현
먼저, 스레드 풀은 여러 개의 스레드를 미리 생성해 놓고 작업을 분배하여 병렬로 처리하는데 사용됩니다. C++11 이상의 표준을 사용한다면, std::thread
와 std::function
을 활용하여 스레드 풀을 쉽게 구현할 수 있습니다.
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
ThreadPool(size_t numThreads) : stop(false) {
for (size_t i = 0; i < numThreads; ++i) {
workers.emplace_back(
[this] {
for (;;) {
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 : workers) {
worker.join();
}
}
private:
std::vector<std::thread> workers;
std::queue<std::function<void()>> tasks;
std::mutex queueMutex;
std::condition_variable condition;
bool stop;
};
위 코드는 ThreadPool
클래스를 정의하고, 생성자에서 원하는 수의 스레드를 만들고 각 스레드는 작업 큐를 확인하여 작업을 차례로 수행하도록 구현되어 있습니다.
작업 로딩 밸런싱
작업 로딩 밸런싱은 각 스레드나 작업자에게 균등하게 작업을 분배하는 기술입니다. 이를 위하여 작업 큐에 들어온 작업을 균등하게 스레드들에게 분배하는 방식을 사용할 수 있습니다.
이를 위한 간단한 예시 코드는 다음과 같습니다.
void distributeWork(const std::vector<std::function<void()>>& allTasks, ThreadPool& pool) {
for (const auto& task : allTasks) {
pool.enqueue(task);
}
}
결론
C++을 사용하여 스레드 풀을 구현하고 작업 로딩 밸런싱을 적용하는 방법에 대해 알아보았습니다. 이러한 방식을 적용하면 멀티스레딩 환경에서 작업을 효율적으로 분배하고 처리할 수 있습니다.