Dans la programmation simultanée C++, l'adoption de modèles de conception peut améliorer la lisibilité, la maintenabilité et l'évolutivité du code. Les modèles courants incluent : le modèle producteur-consommateur : un thread génère des données et d'autres threads consomment des données. Mode lecteur-écrivain : plusieurs lecteurs peuvent accéder aux ressources partagées en même temps, mais un seul rédacteur peut y accéder. Mode moniteur : protège l'accès simultané aux ressources partagées, applique la synchronisation et les contrôles d'état. Mode pool de threads : créez des groupes de threads à l’avance pour éviter la surcharge liée à la création et à la destruction fréquentes de threads.
Modèles de conception courants dans la programmation simultanée C++
En programmation simultanée, l'utilisation de modèles de conception peut améliorer considérablement la lisibilité, la maintenabilité et l'évolutivité du code. Vous trouverez ci-dessous quelques modèles courants dans la programmation simultanée C++ :
Modèle producteur-consommateur
Dans ce modèle, un thread producteur génère des données et un ou plusieurs threads consommateurs consomment les données. Les méthodes d'implémentation courantes utilisent des files d'attente ou de la mémoire partagée.
Exemple :
class Producer { public: void produce(const T& data) { std::lock_guard<std::mutex> lock(queue_mutex); queue.push(data); } private: std::queue<T> queue; std::mutex queue_mutex; }; class Consumer { public: void consume() { std::unique_lock<std::mutex> lock(queue_mutex); if (queue.empty()) { condition_variable.wait(lock); } const T& data = queue.front(); queue.pop(); lock.unlock(); // ... } private: std::shared_ptr<Producer> producer; std::condition_variable condition_variable; std::mutex queue_mutex; };
Mode lecteur-écrivain
Ce mode permet à plusieurs lecteurs d'accéder à des ressources partagées en même temps, mais un seul écrivain peut y accéder. Des verrous réentrants ou des verrous en lecture-écriture sont souvent utilisés pour implémenter ce modèle.
Exemple :
class ReadWriteLock { public: void read_lock() { while (write_locked) { unique_lock<std::mutex> lock(read_mutex); read_count++; } } void read_unlock() { std::lock_guard<std::mutex> lock(read_mutex); read_count--; } void write_lock() { std::lock_guard<std::mutex> lock(write_mutex); while (read_count > 0) { /* 等待读完成 */} write_locked = true; } void write_unlock() { std::lock_guard<std::mutex> lock(write_mutex); write_locked = false; } private: bool write_locked = false; int read_count = 0; std::mutex read_mutex; std::mutex write_mutex; };
Modèle de surveillance
Le modèle de surveillance protège l'accès simultané aux ressources partagées en limitant l'accès aux données à un seul objet. Les objets de surveillance encapsulent les données et les opérations et appliquent la synchronisation et la vérification de l'état.
Exemple :
class Account { public: void deposit(int amount) { std::lock_guard<std::mutex> lock(balance_mutex); balance += amount; } int withdraw(int amount) { std::lock_guard<std::mutex> lock(balance_mutex); if (amount <= balance) { balance -= amount; return amount; } return 0; } int get_balance() { std::lock_guard<std::mutex> lock(balance_mutex); return balance; } private: int balance = 0; std::mutex balance_mutex; };
Mode pool de threads
Le mode pool de threads fournit un groupe de threads pré-créé qui peut être utilisé par les threads clients. En utilisant un pool de threads, vous pouvez éviter la surcharge liée à la création et à la destruction fréquentes de threads.
Exemple :
class ThreadPool { public: ThreadPool(int num_threads) { for (int i = 0; i < num_threads; i++) { threads.emplace_back(std::thread([this] { while (true) { std::function<void()> task; { std::unique_lock<std::mutex> lock(tasks_mutex); if (tasks.empty()) { condition_variable.wait(lock); } task = std::move(tasks.front()); tasks.pop(); } task(); } })); } } void submit(std::function<void()> task) { std::lock_guard<std::mutex> lock(tasks_mutex); tasks.push(std::move(task)); condition_variable.notify_one(); } private: std::vector<std::jthread> threads; std::queue<std::function<void()>> tasks; std::mutex tasks_mutex; std::condition_variable condition_variable; };
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!