6
votes

meilleure façon d'écrire un démon Linux

Pour le travail, j'ai besoin d'écrire un démon TCP pour répondre à notre logiciel client et je me demandais si quelqu'un avait des conseils de la meilleure façon d'y aller.

devrais-je faire une fourchette pour chaque nouvelle connexion comme normalement j'utiliserais des threads?


0 commentaires

7 Réponses :


10
votes

Cela dépend de votre application. Les threads et le forking peuvent tous deux être des approches parfaitement valides, ainsi que la troisième option d'un modèle d'événement à un seul fileté. Si vous pouvez expliquer un peu plus sur ce que vous écrivez, cela vous aiderait à donner des conseils.

Pour ce que ça vaut la peine, voici quelques directives générales:

  • Si vous n'avez pas d'état partagé, utilisez le forking.
  • Si vous avez l'état partagé, utilisez des threads ou un système piloté par événement.
  • Si vous avez besoin de performances élevées sous un très grand nombre de connexions, évitez de vous forger, car il a une surcharge supérieure (en particulier la mémoire). Au lieu de cela, utilisez des threads, une boucle d'événement ou plusieurs fils de boucle d'événement (typiquement un par processeur).

    Forking Généralement sera le plus facile à mettre en œuvre, car vous pouvez essentiellement ignorer toutes les autres connexions une fois que vous avez la fourche; threads le prochain le plus difficile en raison des exigences de synchronisation supplémentaires; La boucle d'événement est plus difficile en raison de la nécessité de transformer votre traitement en une machine à états; et plusieurs threads en cours d'exécution des événements se bouclent les plus difficiles (en raison de la combinaison d'autres facteurs).


2 commentaires

La tenue de mémoire du fourchette n'est pas trop mauvaise, du fait de la manière dont la mémoire de processus est dupliquée copie-écriture. L'inconvénient majeur est le temps nécessaire à la fourchette (), mais si vous ne créez pas et ne détruisez pas les connexions avec une fréquence élevée qui ne devrait pas être un showstopper.


Vrai, mais cela peut être beaucoup plus qu'une petite structure avec un descripteur de fichier et un tampon d'entrée :)



4
votes

Je suggérerais de préparer des connexions sur les threads n'importe quel jour. Le problème avec les threads est l'espace mémoire partagé et la facilité de manipuler la mémoire d'un autre fil. Avec des processus fourchus, toute communication entre les processus doit être intentionnellement faite par vous.

vient de chercher et trouvé cela donc réponse: Quel est le but de Fourchette? . Vous connaissez évidemment la réponse à cela, mais la réponse n ° 1 dans ce fil a de bons points sur les avantages de la fourchette ().


1 commentaires

Un avantage supplémentaire est qu'un thread d'avortement peut être bloqué ou bloqué toute votre application. Comme suggéré dans une autre réponse, vous pouvez créer un bassin de processus de travail. Envisagez de disposer d'un simple processus de délégateur pour faire la queue de travail que le travailleur traite de la file d'attente coopérative. Cette configuration vous donne un meilleur contrôle des ressources système.



1
votes

Outre la bonne réponse de @ Hobodave, un autre avantage de "forking par connexion" est que vous pouvez implémenter votre serveur très simplement, en utilisant inetd ou tcpserver ou similaire : Vous pouvez ensuite utiliser une sortie standard et une sortie standard pour communiquer avec la prise et ne doivent pas avoir à effectuer une gestion de la prise d'écoute (écoute des connexions, etc.), etc.


0 commentaires

1
votes

Une autre option, bien sûr, prépare plusieurs copies du démon et que chacun resterait vivant et continue de répondre à des demandes. Tout dépend de votre application, de vos besoins en charge et de performance attendus, entre autres.

Le moyen le plus simple et le plus simple est d'écrire un démon à base d'inetd; Votre logiciel peut ignorer le fait qu'il fonctionne sur une connexion TCP et gérer simplement l'entrée / la sortie via STDIN / STDOUT. Cela fonctionne bien dans la vaste majorité des cas.


0 commentaires

1
votes

Si vous ne prévoyez pas d'être martelé avec de nombreuses nouvelles connexions par seconde, envisagez de courir de INETD. Sinon ...

Téléchargez la source OpenSSH. Ils ont mis beaucoup de travail dans la séparation des privilèges juste à droite, c'est portable, et il a été examiné pour la sécurité plus que de rien d'autre.

Adaptez-le pour vos besoins, vous pouvez probablement vous en jeter la majeure partie. Respecter le contrat de licence bien sûr. Suivez les futurs correctifs avec un bon CCN.

Ne vous inquiétez pas de la performance des processus de forcement vs threads jusqu'à ce que vous ayez de bonnes preuves, c'est un problème réel. Apache est allé pendant des années et des années à exécuter les sites les plus fréquentés avec le modèle de processus simple-per-client.

Si vous êtes vraiment ambitieux, vous pouvez utiliser une sorte de modèle d'IO asynchrone non bloquant. J'aime Boost.Asio, mais je suis lourd en C ++.

Assurez-vous que votre code gère correctement les signaux. HUP à recharger la configuration. Terme à arrêter de manière gracieusement.

N'essayez pas d'écrire votre propre fichier journal. Utilisez Syslog uniquement ou n'écrivez simplement à STDERR qui peut être redirigé vers Syslog. C'est une véritable douleur qui tente de mettre en place une logrotate sur des serveurs laminés à la maison que tous se connectent légèrement différemment.


0 commentaires

1
votes

Si vous voulez éviter de fileter / de fourrage ensemble, je vous recommanderais d'utiliser tous les E / S non bloquants avec libtevent . Libevent est assez bien connu comme une solution de haute performance pour la programmation entraînée par des événements.


0 commentaires

0
votes

regarder dans ACE (C ++ / Java) . Il possède un certain nombre de réacteurs TCP filetés, événements et forking qui répondent à vos besoins de communication. Vous pouvez également consulter Boost Asio qui fait quelque chose Similaire


0 commentaires