OVH Cloud OVH Cloud

Serveur multithread

16 réponses
Avatar
Flowent
Bonjour,

Voilà je veux faire une petite liste de diffusion personnel :) (comme sympa)
j'ai donc chercher comment faire un serveur en c++, cependant je me heurte à
quelques questions dont je ne trouve pas de solution
-> Vaut il mieux un thread par client, des qu'un client se connecte, hop un
nouveau thread
-> ou plutot un thread par tâche :
- un thread qui attent les clients et les stockes dans une
liste, parcours la liste et si un client a qqchose à dire, il le traite
(utilisation de select/poll) (traitement : connexion a une base de donnees,
recuperation des abonnees, envoi de mails aux abonnées)
- un thread qui envoi les mails
- un thread qui attends les mails du serveur SMTP

Je precise que je suis sur monoprocesseur, la vitesse d'une commande faite
au serveur ne depassera pas les 30ms (le temps de la reconnaitre,
l'executer, envoyer une commande au thread mail, envoyer la reponse ).
Je ne fais aucune supposition sur le nombre de connecté qu'il peut y avoir
simultanément (aussi bien 1 que 2000...)
Je cherche une bonne METHODE pour implementer mon serveur..

merci

6 réponses

1 2
Avatar
Flowent
Mais une autre question se pose, celle des perfomances de l'ordinateur, là
en fait j'ai essayé un ptit serveur avec un seul thread (serveur iteratif en
quelque sorte), j'arrive sans probleme à 300 clients sans que le cpu sature
(voire plus j'ai pas essayé) et les clients n'attende pas (le test
s'effectue en ouvrant 300 sockets, et en envoyant une commande toutes les 8s
par socket, donc ce n'est pas vraiment en même temps mais plus l'un apres
l'autre)

Maintenant imaginons l'autre solution, 300 clients donc 300thread ! est ce
que pour un ordi c'est resonnable? sachant que les thread sont plus ou moins
active (mais ne font pas de gros calcul, juste une connection à une BDD) ?
Avatar
Flowent
Petite precision, pour le test, je lance 300 thread qui ouvre chacune un
socket vers le serveur.
Avec cette methode, le serveur utilise le CPU à 60% environ

Qu'en serai t'il avec 300Thread ?

Merci
Avatar
loufoque
Je vois que ma solution t'a beaucoup intéressée.
C'est pourtant la solution qui permet de gérer le plus de connexions
possibles avec la meilleure performance.
Avatar
Flowent
Ben en fait je faisait deja avec un poll, pour voir si un client avait
quelque chose à dire ! donc les socket asynchrones etaient deja faite :D
Avatar
kanze
Flowent wrote:
Mais une autre question se pose, celle des perfomances de
l'ordinateur, là en fait j'ai essayé un ptit serveur avec un
seul thread (serveur iteratif en quelque sorte), j'arrive sans
probleme à 300 clients sans que le cpu sature (voire plus j'ai
pas essayé) et les clients n'attende pas (le test s'effectue
en ouvrant 300 sockets, et en envoyant une commande toutes les
8s par socket, donc ce n'est pas vraiment en même temps mais
plus l'un apres l'autre)

Maintenant imaginons l'autre solution, 300 clients donc
300thread ! est ce que pour un ordi c'est resonnable?


Pourquoi pas ? Tout dépend de ce que tu fais ; nous en avons
souvent autant, sinon plus, sur nos serveurs. Mais est-ce que tu
auras jamais réelement 300 threads ? D'après ce que j'ai compris
de tes explications, le client ne reste pas connecté. Il se
connecte, envoie une commande, en récupère le résultat, et se
déconnecte.

sachant que les thread sont plus ou moins active (mais ne font
pas de gros calcul, juste une connection à une BDD) ?


Je vois mal un système aujourd'hui qui ne peut pas gérer des
dizaines de milliers de threads. Les choses dont il faut faire
attention sont plutôt :

-- Le coût de l'initialisation d'un thread. Si tu dois gerer
des milliers ou des dizaines de milliers de nouvelles
connexions par séconde, et tu crées un nouveau thread à
chaque connexion, ça peut faire pas mal de charge.

C'est un problème fréquent des serveurs HTTP (où chaque
connexion ne dure typiquement que le temps de récupérer une
page) ; la solution classique est d'utiliser un pool de
threads -- à la fin d'une connexion, le thread ne se termine
pas, mais va se remettre dans le pool, pour servir à une
autre connextion.

-- La communication entre les threads. Si tous les threads sont
constamment en train de travailler, et à accéder aux mêmes
ressources partagées, il risque d'avoir une forte contention
pour les locks, ce qui peut poser des problèmes importants
de performances.

En général, si une connexion a de l'état, et qu'il dure plus
qu'une dizaine de millisécondes, on veut qu'elle ait une
contexte d'exécution qui lui est propre. S'il y a en plus des
ressources importantes en mémoire partagées par toutes les
connexions, on utilise des threads. (Sinon, autant utiliser un
processus par connexion.)

Si la connexion n'a pas d'état, le temps critique devient le
temps de traiter une seule requête. Si ce temps est uniquement
CPU, et on tourne sur un système mono-processeur, il n'y a aucun
intérêt à utiliser les threads. Si le traitement comporte des
opérations qui peuvent être bloquantes, par exemple, il vaut
mieux passer au modèle multi-thread ou multi-processus, afin
qu'un blocage sur une requête ne bloque pas tout le monde.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
Flowent wrote:

Petite precision, pour le test, je lance 300 thread qui ouvre
chacune un socket vers le serveur. Avec cette methode, le
serveur utilise le CPU à 60% environ

Qu'en serai t'il avec 300Thread ?


Essaie. Sur ma machine, un read sur un socket ne prend pas de
CPU, tant qu'il n'y a pas de données disponisbles. La même chose
n'est pas vrai pour un select ou un poll. Mais a priori, 60% du
CPU, avec 300 connexions, laisse penser que c'est réelement le
traitement des requêtes qui prend le temps. Et ça, ça serait
pareil, quelque soit le modèle utilisé.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

1 2