IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation et administration système Perl Discussion :

Thread && socket.accept


Sujet :

Programmation et administration système Perl

  1. #1
    Membre actif Avatar de Balbuzard
    Profil pro
    Inscrit en
    Août 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 381
    Points : 263
    Points
    263
    Par défaut Thread && socket.accept
    Bonjour à tous;

    J'ai un processus perl qui reçoit des données d'un pipe et les traite.
    Je dois rajouter des données venant du réseau.
    J'ai construit un serveur TCP qui fait bien le travail, indépendamment du premier processus, et c'est dommage, car les deux processus travaillent sur des données qui peuvent être identiques.
    Donc j'ai pensé à inclure ce serveur dans le premier processus pour qu'il puisse vérifier si les données qu'il reçoit du réseau sont déjà présentes, et dans ce cas, les droper.

    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my $server = server->new();
    my $thread = threads->create(sub {$server->server();});
    my $thread2 = threads->create(sub {
    while(<STDIN>) {
        ...instructions et traitement des données ...
    Donc je lance le processus. Il se lance correctement et fait les tâches de traitement des données venant du pipe.
    Je me connecte en telnet. La connexion se fait sans problème. Mais les données que j'envoie au serveur ne sont pas traitées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub server {
    	my($self) = @_;
    	while (my $client = $serveur->accept()) {
    		next if my $pid = fork;
    		print "\n*** Connected ***\n"; # -> ça s'affiche bien
    		print "--- I am PID $$ ---\n"; # ça s'affiche aussi
    		my $message = "";
    		while( my $rep = <$client> ) {
    			print "oui\n"; # -> ça ne s'affiche pas
    Je pense que la ligne blocante est celle en gras. Mais je ne vois pas de moyen de m'en sortir du coup: Si la méthode accept est blocante, je ne peux jamais mettre ça dans un thread :-S Il doit bien y avoir une solution? Ce problème me parait basique, mais google ne m'a pas trop aidé :-S
    Merci pour vos conseils/remarques/suggestions!
    ZORRO
    Plus Vengeur que Masqué

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je t'invite alors à utilise IO::Select (si tu n'es pas sur une plateforme Windows/ActiveState). Avec cet objet, tu peux configurer plusieurs handle et utiliser la méthode can_read afin de savoir, apriori, si tu peux lire quelque chose sur un handle.

    Je recherche le fil où l'on en a parlé récemment.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    La limitation d'ActivePerl pour IO::Select concerne STDIN. Voir ici, ainsi que le fil complet dans lequel je donne une exemple fonctionnel de client de tchat qui accepte une connexion socket et clavier.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  4. #4
    Membre actif Avatar de Balbuzard
    Profil pro
    Inscrit en
    Août 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 381
    Points : 263
    Points
    263
    Par défaut
    Hello,Philou67430!
    Merci pour ta réponse;

    Je me suis demandé si le processus de fork n'était pas plus intéressant; mais j'ai pile le même problème :-S

    Donc pour le IO::Select:
    Je me demande en quoi ça résout le problème de blocage lors du socket->accept()?
    ZORRO
    Plus Vengeur que Masqué

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Mmmh... bonne question. En fait, je n'avais pas vu que ton blocage se situait à ce niveau.
    Mais la réponse est en fait simple : en lisant la doc de IO::Select->accept, il est indiqué qu'une simple utilisation de select avec un timeout de 0 permet de résoudre ce problème :
    accept([PKG])
    perform the system call "accept" on the socket and return a new
    object. The new object will be created in the same class as the
    listen socket, unless "PKG" is specified. This object can be used
    to communicate with the client that was trying to connect.

    In a scalar context the new socket is returned, or undef upon
    failure. In a list context a two-element array is returned
    containing the new socket and the peer address; the list will be
    empty upon failure.

    The timeout in the [PKG] can be specified as zero to effect a
    "poll", but you shouldn't do that because a new IO::Select object
    will be created behind the scenes just to do the single poll. This
    is horrendously inefficient. Use rather true select() with a zero
    timeout on the handle, or non-blocking IO.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Quoique, si l'usage de select te rebute, il me semble que rien ne t'empêche d'utiliser IO::Select pour vérifier à priori si $serveur contient à socket à accepter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    my $sel = IO::Select->new($serveur);
     
    while () {
      if ($sel->can_read() && my $client = $serveur->accept()) {
      }
      ...
    }
    Par ailleurs, en te relisant, tu indiquais que la ligne grasse était la ligne bloquante. Je suis confus
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

Discussions similaires

  1. tuer un thread en attente (socket)
    Par LesLemmings dans le forum Visual C++
    Réponses: 1
    Dernier message: 18/03/2007, 09h50
  2. Les threads et les sockets
    Par pier* dans le forum Développement
    Réponses: 4
    Dernier message: 09/01/2006, 11h44
  3. [WinSock] Question sur les sockets (accept)
    Par Grey dans le forum MFC
    Réponses: 3
    Dernier message: 09/01/2006, 11h37
  4. thread, socket, Accept, Receive
    Par lacousine dans le forum MFC
    Réponses: 4
    Dernier message: 20/04/2005, 00h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo