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

Interfaçage autre langage Python Discussion :

Appel d'un fonction C sous Python et blocage des autres threads


Sujet :

Interfaçage autre langage Python

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut Appel d'un fonction C sous Python et blocage des autres threads
    Bonsoir à tout le monde,

    J'ai cherché mon problème toute la journée, sans succès. Et même sur ce forum, je n'ai rien trouvé... Je vous écris donc en espérant trouvé quelqu'un qui ait des pistes ou mieux, connaisse la solution à mon problème! Pour celà, je vais tenter d'être le plus clair possible.

    J'ai un script Python qui utilise le module Numeric et qui démarre une "thread" servant à communique avec un serveur distant. D'autre part, celle-ci, en plus, va suivre l'évolution d'une valeur dans un tableau créée par Numeric. Jusque là, aucun souci. Les messages en provenance du client atteignent le serveur sans aucun os (Le client transmet en fait certaines valeurs contenues dans le tableau).
    Le problème provient lorsque je démarre une autre "thread". Cette dernière n'est rien d'autre qu'un "process" qui appelle une fonction contenue dans une librairie C. Vous vous en doutez, cette fonction va modifier le tableau Numeric créée précédemment et ainsi modifier la valeur de certaines "cases" du tableau. Le client n'aura ensuite qu'à transmettre la nouvelle valeur au serveur. Il est essentiel de noter là que l'utilisation d'un tableau Numeric est beaucoup plus appréciable que l'appelle à des modules ctypes.
    Mais là, une fois démarré, la première "thread" ne progresse plus, comme si elle était bloquée.

    Je me questionne donc, car Python est sensé utiliser le GIL qui permet d'allouer un certain temps pour chaque thread lancée en bloquand temporairement les autres.
    D'autre part, je ne peux pas faire appel aux fonctions Py_BEGIN_ALLOW_THREADS puisque la fonction C va accéder à des variables qui sont aussi en fait des objets Python.

    Je tiens aussi à préciser que tant que je ne démarre que des threads qui agissent sous Python, toute les threads procèdent normalement. C'est seulement avec la thread qui fait appel à une librairie C que ça plante.

    Quelqu'un aurait-il une idée ?

    Merci par avance,
    Mickaël

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Points : 139
    Points
    139
    Par défaut
    Bonjour,

    le GIL est un lock qui permet de réguler l'accès aux objets python. Si jamais tu le gardes en permanence dans ta lib C, tous les autres threads seront bloqués. Il faut donc ou bien n'avoir dans une librairie C que des fonctions "rapides" à exécuter (c'est à dire qui ne bloquent pas) ou bien relâcher le lock avec Py_BEGIN_ALLOW_THREADS dans les parties de la lib qui prennent du temps (je suppose qu'elle doit bloquer sur un event ou un wait?).

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Bonsoir Fructivor,

    Avant tout merci pour ta réponse rapide, claire, et en soit on ne peut plus logique.
    Dis-moi si je me trompe, mais d'après ce que j'ai pu lire, lorsque ma fonction en C est invoquée, elle va être bloquante pour les autres threads sans même que je ne lui demande de le faire, et ce jusqu'à aboutir à la fin de la fonction.

    En fait, ma fonction est lourde en calculs, la phase Python n'étant en soit qu'un "wrapper" et un "seeker". Néanmoins, elle peut se décomposer en différentes étapes, pendant lesquelles, parfois, le tableau Numéric n'est pas modifié, mais seulement lu (Je précise là que le "seeker" Python ne modifie absolument rien aux tables, il ne fait que les lire pour les transmettre à un serveur central).

    J'aimerais par conséquent ajouter deux questions à ce sujets:
    1. Est-il possible d'utiliser le Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS où je veux dans ma librairie C (du moins, je sous-entends dans les limites du raisonnable) et puis-je les faire apparaître plusieurs fois, dans l'idée qu'elles cerneront les parties pertinentes de la fonction C ?
    2. Puisque le "seeker" de Python ne fait que lire une zone mémoire sans la modifier, ne serait-il pas plus judicieux de simplement mettre la fonction C entre les balises Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS de sorte à ce qu'elle tourne "en arrrière plan" ?
    3. Mais comment faites-vous pour utiliser ces balises. Pour être honnête, même la documentation fournie par le site de Python est incompréhensible! :S On ne sait jamais comment utiliser les balises, où les placer et encore moins les déclarer! Quelqu'un pourrait-il me donner un exemple vraiment basique de la façon dont je dois utiliser ces balises (J'ai cherché partout sans succès) ? Comment le signale-je à Python, à la fonction C ?

    Encore merci pour votre aide,
    Mickaël

  4. #4
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Bonjour à tous,

    J'ai finalement trouvé la réponse en "tâtonnant" un peu. La solution en soit était évidente en ce sens que les balises Py_BEGIN_ALLOW_THREADS et Py_END_ALLOW_THREADS ne sont rien d'autres que de simples macros regroupant un ensemble de commandes plus "basiques".

    Ainsi, pour les calculs de la fonction C qui ne modifient pas le tableau Numeric qui est partagé avec l'interface Python, il suffit de les encadrer par les deux balises précédemment citées.

    Encore merci,
    Mickaël

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Appel d'une fonction ou d'un fichier dans un autre fichier
    Par Huifortrack dans le forum Général JavaScript
    Réponses: 20
    Dernier message: 13/06/2014, 16h10
  2. Fonction randint sous Python
    Par circe dans le forum Général Python
    Réponses: 3
    Dernier message: 10/12/2010, 11h22
  3. Réponses: 2
    Dernier message: 04/03/2010, 16h59
  4. Appel d'une fonction depuis sous formulaire
    Par El_Manu dans le forum VBA Access
    Réponses: 7
    Dernier message: 02/11/2007, 18h21
  5. Fonction addslashes sous Python ?
    Par ecocentric dans le forum Général Python
    Réponses: 2
    Dernier message: 28/01/2006, 19h27

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