Bibliothèque de réseaux C ++ minuscule
| Partie ⅰ | Partie ⅱ | Partie ⅲ | Partie ⅳ | Partie V | Partie ⅵ | Partie ⅶ |
|---|
| Introduction du projet | Caractéristiques du projet | Environnement de développement | Modèle de concurrence | Construire un projet | Cas de course | Explication du module |
Introduction du projet
Ce projet est une bibliothèque de réseaux multi-thread basée sur le modèle de réacteur implémenté par Muduo. En utilisant C ++ 11 pour écrire pour supprimer la dépendance de Muduo à Boost, un petit serveur HTTP est implémenté en interne, ce qui peut prendre en charge les demandes et l'accès aux ressources statiques, et s'accompagne de journaux asynchrones pour surveiller la situation du serveur.
Le projet a implémenté le module de canal, le module de polleurs, le module de boucle d'événements, le module HTTP, le module de minuterie, le module de journal asynchrone, le module de pool de mémoire et le module de pool de connexion de base de données.
Caractéristiques du projet
- La couche sous-jacente utilise le modèle de multiplexage d'E / S du mode Epoll + LT et implémente le modèle de réacteur maître-esclave en combinaison avec des E / S non bloquantes.
- Adoptez le modèle de thread "une boucle par thread" et encapsulez le pool de threads vers le haut pour éviter les frais généraux de performances causés par la création et la destruction du fil.
- EventFD est utilisé comme descripteur de notification d'événement pour faciliter une répartition efficace des événements à d'autres threads pour effectuer des tâches asynchrones.
- Les journaux asynchrones sont implémentés sur la base de tampons doubles auto-implémentés, et le thread backend est responsable de la rédaction régulière des informations du journal frontal au disque pour éviter de bloquer les services réseau lorsque les données tombent du disque.
- La structure de gestion de la minuterie est mise en œuvre sur la base de l'arborescence rouge et noir, et le TIMERFD de Linux est utilisé en interne pour informer les tâches d'expiration, et les tâches chronométrées sont gérées efficacement.
- Suivez les techniques RAII pour gérer la mémoire à l'aide de pointeurs intelligents pour réduire le risque de fuite de mémoire.
- Utilisez des machines d'État finies pour analyser les paquets de demande HTTP.
- Se référant à Nginx, le module de pool de mémoire est implémenté pour mieux gérer un petit espace mémoire et réduire la fragmentation de la mémoire.
- Le pool de connexions de la base de données peut gérer dynamiquement le nombre de connexions, générer ou détruire les connexions en temps opportun et assurer les performances du pool de connexions.
Environnement de développement
- Système d'exploitation:
Ubuntu 18.04.6 LTS - Compilateur:
g++ 7.5.0 - Éditeur:
vscode - Contrôle de version:
git - Construction du projet:
cmake 3.10.2
Modèle de concurrence
Le projet adopte le modèle de réacteur-esclave.
Après avoir appelé la fonction de démarrage de TCPServer, un pool de threads sera créé en interne. Chaque fil exécute une boucle d'événement indépendamment, à savoir le sous-réacteur. Le MainReacteur interroge le sous-réacteur du pool de threads et le dépasse à une nouvelle connexion. Il existe de nombreux avantages à utiliser le modèle de réacteur maître-esclave:
- Réponse rapide et ne doit pas être bloquée par un seul événement de synchronisation, bien que le réacteur lui-même soit toujours synchrone;
- Il peut éviter les problèmes complexes de multi-threading et de synchronisation dans la plus grande mesure et d'éviter la commutation multi-threading / procédé;
- Il a une bonne évolutivité, ce qui peut faciliter la pleine utilisation des ressources CPU en augmentant le nombre d'instances de réacteur;
- La réutilisabilité est bonne et le modèle de réacteur lui-même n'a rien à voir avec la logique de traitement d'événements spécifique et a une réutilisabilité élevée;
Construire un projet
Installer Cmake
sudo apt-get update
sudo apt-get install cmake
Télécharger le projet
Exécuter le projet de construction de script
cd ./tiny-network && bash build.sh
Cas de course
Ici, nous prenons un simple serveur Echo comme cas, et le port d'écoute par défaut d' EchoServer est 8080 .
cd ./example
./EchoServer
État de l'implémentation:
Le module http possède un petit cas de serveur HTTP qui peut également être exécuté. Son écoute par défaut 8080 :
cd ./src/http && ./HttpServer
Explication du module
Certains modules ici configureront le code source Muduo pour expliquer, et certains utilisent le code source de ce projet, mais les idées d'implémentation sont cohérentes.
Module de canal
Module de prélèvement
Module EventLoop
Module de tampon
Module de minuterie
Module HTTP
Module de journal asynchrone
Module de piscine de mémoire
Module de pool de connexion de la base de données
Plan d'optimisation
- Prévoyez de mettre en œuvre l'horodatage sous-jacent à l'aide de STD :: Chrono
- Gérer la structure de la minuterie en utilisant la file d'attente prioritaire
- Couverture plus de tests unitaires
reconnaissant
- "Programmation du serveur haute performance Linux"
- "Linux Multithread Server Programming: Utilisation de la bibliothèque de réseau Muduo C ++"
- https://github.com/chenshuo/muduo