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

Python Discussion :

Programme avec processes et utilisation de popen


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut Programme avec processes et utilisation de popen
    J'ai un programme en python avec une fonction que je veux pouvoir éxécuter plusieurs fois en parallèle. Or, cette fonction contient un appel à un fonction de bash (je suis sous Linux) via popen. L'appel à la fonction est donc bloquant.
    J'ai constaté que si je fait juste n threads qui éxécute chacun cette fonction, ceux-ci s'éxécutent les uns à la suite de l'autre et non en parallèle.
    D'après ce que j'ai lu sur internet c'est normal. Il faudrait que j'utilise des process via os.fork().
    Ce lien explique comment créer un processus fils. Le problème c'est que j'ai besoin de créer n processus fils et j'ai du mal à concevoir ma structure de données et mon algorithme pour lancer mes n process.
    Je pense créer un tableau d'entier pour pouvoir stocker tous les pids et attendre tous mes process. Mais cela ne résoud pas le problème du lancement des n process.
    Si vous avez des liens et/ou des exemples de programmes faisant ce travail, je suis preneur.
    Merci

  2. #2
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Salut,

    Il y a quelque chose que je ne comprends pas, si tu fait un popen dans un thread, pourquoi cela bloquerait-il les autres threads ???
    Normalement ils devraient continuer à s'exécuter. Tu pourrais ainsi éviter de forker pour créer des processus (ce qui est plus lourd à mettre en place). Il y a surement quelque chose qui pose pb. dans ton code.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Bah en fait, c'est juste une constatation pratique.
    Le fait est que lorsque je lance mon programme, la durée d'éxécution est quasiment la même entre 50 threads et 50 fois la fonction du threads lancée à la suite.
    Et surtout, j'ai récupéré un lien qui disait que popen bloquait l'éxécution parallèle des threads et que pour avoir du parallélisme, il fallait passer par des process.
    Mais, je vais rejeter un coup d'oeil au code.

  4. #4
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Première page de man trouvée par Google sur popen :

    Citation Envoyé par man popen(3)
    La fonction popen() engendre un processus en créant un tube (pipe), exécutant un fork(), et en invoquant le shell. Comme un tube est unidirectionnel par définition, l'argument type doit indiquer seulement une lecture ou une écriture, et non pas les deux. Le flux correspondant sera ouvert en lecture seule ou écriture seule.
    N'oublie pas non plus de faire un pclose() pour fermer le flux ET SUROUT PAS de fclose (d'après ce qui est dit dans cette page de manuel).

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Bon, en fait j'ai résolu ce problème. Je suis arrivé à faire des threads qui s'éxécute en parallèle.

    Mais j'ai un autre problème. En fait chaque thread lance des pings pour trouver des adrresses IP valides jusqu'à ce que le nombre d'IP demandées soit atteint. Et dès que le nombre de threads augmente (en gros, dès qu'il est supérieur à 10), j'ai l'erreur suivante : connect: Argument invalide.
    Je suppose que les threads étant trop nombreux, ils arrivent pas à tous lancer les Ping via Popen.
    Comment puis-je contourner ce problème ?

  6. #6
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Non je ne pense pas. D'après le message d'erreur, le problème se situerai plutôt au niveau des pipes et pas des thread. J'avoue que je ne vois pas vraiment de solution. Tout ce que je peux te dire c'est de chercher peut-être du côté des limites du système sur le nombre max. de sockets ouvertes en même temps ou nombre max de descripteur de fichiers.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Je suis quasi sûr que ça vient des sockets car en fait, le problème se produit lorsque je lance Popen sur le ping. Je récupère alors 0 lignes sur le résultat de la commande ping alors qu'en théorie (et même en cas de timeout) je devrais récupérer au moins 5 ou 6 lignes.

    En fait, c'est comme ça que j'ai trouvé le problème à l'origine : l'absence de ligne dans le résultat faisait planter mon programme d'analyse Là j'ai corrigé pour ne pas traiter le résultat de la commande en cas d'absence de ligne, mais c'est pas pour ça que j'ai plus l'erreur : connect: Argument invalide.

  8. #8
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Si tu est sous Windows regarde les valeurs renvoyées dans WSAData renvoyé après appel à WSAStartup(). Et dis nous ce que donne iMaxSockets.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Bah je suis sous Fedora Core 7 en fait.
    Si t'as la commande correspondante...

  10. #10
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Arg, ... Linux ça remonte à très loin dans mes souvenirs. Si jamais un Linuxien passe par là, qu'il se manifeste.

    Au mieux, ce que je peut te dire c'est d'essayer de limiter le nb. de threads à 10. Typiquement on utilise une sémaphore pour ça.

    J'y penses, quand tu lance les commandes ping est-ce qu'elles pointent toutes vers le même host ?

    Ce que tu peut aussi tester c'est de remplacer la commande ping par un wget (si tu la connais un peu) pour voir si la barre des 10 threads peut être dépassé sans bloquage des sockets. Elles mettent en oeuvre des protocoles fondamentalement différents, et l'une peut très bien bloquer alors que la deuxième non.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    Pour la limitation à 10, mon but est justement de trouver un maximum d'adresses valides en un minimum de temps, c'est pour ça que je veux utiliser beaucoup de threads.

    Pour les Ping, a priori, aucun ping n'est lancé vers une adresse déjà pinguée auparavant.

    Pour wget, je viens de survoler le man mais je pense pas que je puisse récupérer les RTT avec cette commande.

  12. #12
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    On s'est mal compris. La command wget n'a pas comme but de remplacer ce que fait un ping.

    C'est juste qu'un ping envoi des paquets ICMP qui peuvent être filtrés, ignorés, temporisés par les routeurs et serveurs, ... bref c'est pas ultra-rapide. Au contraire, wget utilise HTTP qui est trés rapide et pas filtré.

    Mais tu peut aussi très bien faire un system("ls -1 ./*"); Le but étant de vérifier que ce n'est pas la commande ping qui pose problème.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 26
    Par défaut
    En fait, j'ai trouvé qu'il restait encore une plage d'adresse IP que je générais (aléatoirement) qui étaient invalides et que je scannais quand même.

    Pour les sockets, en faisant des tests, j'ai remarqué que je pouvais en faire à peu près 330 sans problème, donc ça ne vient pas de là, c'est sur.

    Le problème est donc résolu. J'en ai d'autres sur le feu, mais c'est plus de l'algorithmique et du traitement de résultat de commandes que des problèmes liés au langage.

Discussions similaires

  1. Utiliser les informations crées par un programme avec IDle
    Par magalii dans le forum Programmation multimédia/Jeux
    Réponses: 1
    Dernier message: 23/04/2015, 02h01
  2. Comment lancer un programme java avec Process?
    Par stpaul04 dans le forum Débuter avec Java
    Réponses: 15
    Dernier message: 20/02/2011, 23h52
  3. Réponses: 3
    Dernier message: 03/11/2008, 20h54
  4. Réponses: 3
    Dernier message: 09/02/2004, 14h35
  5. Réponses: 3
    Dernier message: 27/08/2003, 21h14

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