Xavier Lamorlette

C++ : Multithreading

Sommaire :

Fonction asynchrone avec std::async

int do_something(char a) {
    return 1;
}

{
    std::future future_something = std::async(std::launch::async, do_something, 'a');
    […]
    int value = future_something.get();
}

Utilisation avec une méthode :

void A::foo() {
    std::future future_something = std::async(std::launch::async, & A::do_something, this, 'a');
    […]
    int value = future_something.get();
}

int A::do_something(char a) {
    return 1;
}

Note : l'exécution dans un thread séparé n'est pas garantie.

Implémentation d'un worker générique avec std::thread

Voici une implémentation d'un worker générique, avec des callabacks, en utilisant les techniques de Mixin et de RAII.

Worker générique :

class Worker_interface {
public:
    virtual ~Worker_interface() = default;

    virtual void start() {
        alive = true;
    }

    virtual void stop() {
        alive = false;
    }

protected:
    bool alive = false;
};

template <typename Worker_base>
class Worker: public Worker_base {
public:
    using Worker_base::Worker_base;

    Worker(const Worker &) = delete;
    Worker(Worker &&) = default;

    ~Worker() override {
        stop();
    }

    void start() override {
        Worker_base::start();
        runner = std::thread([this] {
            this->run();
        });
    }

    void stop() override {
        Worker_base::stop();
        if (runner.joinable()) {
            runner.join();
        }
    }

private:
    std::thread runner;
};

Utilisation du worker générique :

class My_worker_base: public Worker_interface {
public:
    My_worker_base(Callback & callback):
        callback(callback) {
    }

protected:
    void run() {
        …
        callback(…);
    }

private:
    Callback & callback;
};

using My_worker = Worker<My_worker_base>;

Utilisation du worker :

{
    My_worker my_worker(callback);
    my_worker.start();
    …
}

thread_local

Pour les variables globales et statiques, permet de séparer les instances de chaque thread.

thread_local int x;

Références

Threading:

La dernière mise à jour de cette page date de janvier 2023.

Le contenu de ce site est, en tant qu'œuvre originale de l'esprit, protégé par le droit d'auteur.
Pour tout commentaire, vous pouvez m'écrire à xavier.lamorlette@gmail.com.