Ugrás a tartalomhoz

thread pool

A Wikiszótárból, a nyitott szótárból


Főnév

thread pool (tsz. thread pools)

  1. (informatika) A Thread Pool (szálkészlet) egy haladó szintű programozási technika, amely lehetővé teszi, hogy előre létrehozott szálakat (threadeket) használjunk feladatok (taskok) végrehajtására anélkül, hogy minden egyes feladatnál új szálat hoznánk létre. Ez jelentős teljesítményjavulást eredményez, különösen nagy számú, rövid életű vagy párhuzamos feladathoz.



🧠 Mi az a Thread Pool?

Lényeg:

  • Létrehozunk N darab szálat előre (általában a CPU magok számához igazítva)
  • A program feladatokat (taskokat) tesz be egy munka sorba (task queue)
  • A szálak folyamatosan figyelik a sort, és végrehajtják a feladatokat
  • Ha nincs feladat, a szálak várakoznak



✅ Előnyei

Előny Magyarázat
Szálak újrahasználata Nem kell minden feladathoz új std::thread
Kevesebb memória- és CPU-költség A szál létrehozása drága művelet
Könnyen méretezhető CPU-magok számához igazítható
Várakozás és szinkronizáció kezelhető condition_variable segítségével



🛠 Egyszerű Thread Pool C++-ban (C++11)

🔧 Implementáció

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

class ThreadPool {
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;

    std::mutex queueMutex;
    std::condition_variable condition;
    std::atomic<bool> stop;

public:
    ThreadPool(size_t threads) : stop(false) {
        for (size_t i = 0; i < threads; ++i) {
            workers.emplace_back([this] {
                while (!stop) {
                    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(); // Feladat végrehajtása
                }
            });
        }
    }

    // Feladat hozzáadása a poolhoz
    void enqueue(std::function<void()> task) {
        {
            std::lock_guard<std::mutex> lock(queueMutex);
            tasks.push(std::move(task));
        }
        condition.notify_one(); // Ébreszt egy szálat
    }

    ~ThreadPool() {
        stop = true;
        condition.notify_all(); // Minden szálat ébreszt
        for (std::thread& worker : workers)
            worker.join();
    }
};

🧪 Használat:

int main() {
    ThreadPool pool(4); // 4 szálas pool

    for (int i = 0; i < 10; ++i) {
        pool.enqueue([i] {
            std::cout << "Feladat " << i << " szálon fut.\n";
        });
    }

    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 0;
}

🧩 Fejlesztési lehetőségek

Téma Leírás
std::future integrálása Lehetővé teszi visszatérési érték lekérését aszinkron módon
Prioritásos feladatok Speciális priority_queue
Dinamikus szálkezelés Szálak számának növelése vagy csökkentése terhelés alapján
Task cancel Lehetőség feladat törlésére, ha még nem kezdődött el



📦 STL alternatíva

C++17-től: std::async() használható alap szintű párhuzamosításra, de nem implementál valódi thread poolt, és nem tudod újrahasználni a szálakat.

auto f = std::async(std::launch::async, [] {
    std::cout << "Async futtatás\n";
});

⚠️ Buktatók

  • std::function<void()> dinamikus allokációt használ
  • Megfelelő join() és erőforrás kezelés elengedhetetlen
  • Különösen fontos a versenyhelyzetek (race conditions) elkerülése
  • A queue lehet lock-free vagy bounded, ha teljesítménykritikus



🎯 Összefoglalás

A Thread Pool egy hatékony megoldás, ha:

  • sok rövid ideig futó, párhuzamos feladatot kell kezelni,
  • el akarod kerülni az új szálak létrehozásának költségeit,
  • irányítani szeretnéd, hogy hány szál dolgozik egyszerre.