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

Déploiement/Installation Python Discussion :

Cx_freeze : Crash du .exe à cause d'appels récursifs de fonctions


Sujet :

Déploiement/Installation Python

  1. #1
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut Cx_freeze : Crash du .exe à cause d'appels récursifs de fonctions
    Bonjour,

    J'ai développé une petite application qui utilise beaucoup d'appels récursifs. Je l'ai mis au point sous Python 2.7.8 et elle fonctionne correctement après que j'ai ajouté la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import sys
    sys.setrecursionlimit(10000)
    J'ai fabriqué un exécutable avec cx_freeze sans aucune erreur. Le setup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
     
    import sys
    from cx_Freeze import setup, Executable
     
    base = None
    if sys.platform == "win32":
        base = "Win32GUI"
     
    executables = [
            Executable("main.py", base=base)
    ]
     
    buildOptions = dict(
            compressed = True,
            packages = ["sqlalchemy"], 
            excludes = ["Tkinter", "tcl", "ttk", "tkinter*​"],
            path = sys.path + ["modules"]
            )
     
    setup(
        name = u"Application LN 2016",
        version = "1.1.0",
        description = u"Assistant de révision",
        options = dict(build_exe = buildOptions),
        executables = executables, 
        )
    Le programme se lance normalement, toutes les options fonctionnement correctement sauf l'option avec les appels récursifs qui plante l'application.

    Est-ce un comportement normal ? Comment peut-on contourner ce problème ?
    Merci d'avance pour vos pistes.

  2. #2
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Salut Triton972,

    Je ne suis pas un grand expert Cx_Freeze, car je ne m'en sert qu'en mode basique, et qui plus est, sans appel recursif. Cependant, je connais une petite chose qui pourrait potentiellement expliquer ton probleme. Sous Windows (je suppose que c'est ton cas), le path d'acces aux module est différent entre l'execution pur du script, et l'execution de l'exe.

    Pour ce soucis, je te renvoie vers ce post.

    Il s'agit de mes quelques notes sur cx_freeze.

    EN dehors de cette potentielle anomalie, je ne sait pas ce qui pourrait te gêner.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  3. #3
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    Bonjour deusyss,

    Merci pour ta piste que je vais explorer de ce pas.
    A quel niveau dois-je invoquer ta fonction :
    #!/usr/bin/env python
    #-*- coding:utf-8 -*

    import os
    import sys

    #===================================================#
    # Obtention du bon chemin d'execution #
    #===================================================#
    def cxf_get_path():
    """
    Allow to know the good path under Linux, MAC, and Windows.
    Under Windows, adapt the path betwwen direct execution or
    trough cx_freeze or PYXMAKER

    PARAMETERS
    ==========
    None

    RETURNS
    =======
    The execution path, adapted to the situation
    """
    #OS = Linux
    if sys.platform == 'linux2':
    path = os.path.dirname(os.path.abspath(__file__))

    #OS = Windows
    elif sys.platform in ("win32", "cygwin"):
    if getattr(sys, 'frozen', False):
    path = os.path.dirname(sys.executable)
    else:
    path = os.path.dirname(os.path.abspath(__file__))

    #OS = MAC
    else:
    path = os.path.dirname(os.path.abspath(__file__))

    return path
    Merci d'avance
    @+

  4. #4
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Salut,

    Ma fonction te permets d'obtenir toujours un chemin valide sous windows, que tu execute directement le script Python, ou que tu lance un exe. En effet, un __file__ ne te renverra pas la meme chose selon qu'il est en .py ou en .exe. Le piege se trouve là.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    N'étant pas spécialiste de cette question, mais poussé par la curiosité, j'ai fait un petit test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Python 3
     
    import sys
     
    #############################################################################
    def toto(c=0):
        print(c)
        c += 1
        toto(c)
     
    #############################################################################
    if __name__ == "__main__":
        pilemax = 1000
        sys.setrecursionlimit(pilemax)
        print(sys.getrecursionlimit())
        try:
            toto()
        except Exception:
            pass
    Avec pilemax=1000, l'exception à cause du dépassement de la pile arrive à 997. Après traitement par cx_freeze, on arrive à peu près au même résultat. Jusque là, tout va bien.

    Avec pilemax=10000, on arrive à 6695, et pour l'exe: 3419. Donc, en passant de 1000 à 10000 on gagne, mais pas complètement, et avec l'exe, c'est encore moins!

    Avec pilemax=50000, les résultats sont les mêmes, tant pour le code .py que pour l'exe!!! Donc, au delà de 10000, on ne gagne plus rien!

    Bizarre, bizarre... Pourtant, je fais ça sur un PC récent avec une grosse mémoire (16Go), Windows 8.1 64bits et Python 3.4. Mais c'est Python "32bits" seulement: peut-on améliorer avec Python 64bits?.

    Quelqu'un peut-il expliquer ces curieux résultats?


    En fait, la seule règle que je connaisse en Python sur ce point précis, et que j'applique systématiquement, c'est: coder pour éviter la récursion.

    Mais il est vrai que pour certains problèmes qui sont récursifs par nature (recherche dans un arbre par exemple), le codage sans récursion peut amener pas mal de complexité, et en tout cas un code beaucoup moins élégant à la lecture.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    Merci pour vos contributions.

    En fait, je cherche à reproduire, en python pur, un script écrit en SWI-PROLOG (d'où les appels de récursivité). Il existe bien un module (pyswip) qui permet de faire cela.
    Cà fonctionne bien avec Python mais je n'y arrive pas avec Django qui est une des finalités du projet.

    J'ai donc "bricolé" un petit système sans prétention qui est censé reproduire, à peu près, le fonctionnement de PROLOG (pas d'éxécution non-déterministe).
    C'est à dire pour être court, de satisfaire un but par la résolution de clauses elles mêmes constituées de sous-buts.
    Si la clause 1 échoue on essaie la clause suivante, si elle réussit, le but réussit.
    Si aucune clause réussit, le but échoue.

    Voilà ce que j'ai fait :

    Je passe un dictionnaire de paramètres d'entrée à une fonction seq5 (le but à satisfaire)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	...
            kw = {'param1': param1, 'param2': param2, 'param3': param3}
            seq5(**kw)
    	... suite du traitement en python ...
    la fonction seq5, elle-même, appelle une autre fonction (sous-but) : seq7

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
            def seq5(**kw):
     
                def c1(**kw):
     
                    calcul ...
                    if calcul<= quelquechose:
                        return None       		# c1 échoue, il faut essayer c2. Le generator s'en occupe          
     
                    autre traitement ...
                    kw1 = dict(kw)			# je duplique les paramètres que j'ajuste en fonction de l'algorithme
    		traitement de kw1 ...
     
                    if seq7(**kw1) is None:         # on teste seq7. S'il échoue, c1 échoue donc seq5 échoue
                        return None
                    return True			# sinon c1 réussit donc seq5 réussit
     
                def c2(**kw):
     
    		# si c1 échoue on essaie de satisfaire c2
    		# pour que c2 réussise il faut faire réussir seq5 avec d'autres paramètres
     
    		traitement de kw1 ...
                    kw1 = dict(kw)
     
                    if seq5(**kw1) is None:		# Si l'appel récursif de seq5 échoue, le premier appel de seq5 échoue ... 
                        return None
                    return True            		# Sinon il réussit
     
    	    # on définit l'ordre des clauses dans tuple qui est balayé par le generator si la clause concernée échoue, jusqu'à la dernière
     
                clauses = c1, c2,
                return next((x for x in (clause(**kw) for clause in clauses) if x), None)
    La fonction seq7 est sur le même principe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
            def seq7(**kw):
     
                def c0(**kw):
    		# clause d'arrêt
                    calcul0
                    return (calcul0)
     
                def c1(**kw):
                    traitement1 ...
     
                    kw1 = dict(kw)
    		traitement de kw1 ...
                    if seq7(**kw1) is None:
                        return None
                    return True
     
                def c2(**kw):
                    traitement2 ...
     
                    kw1 = dict(kw)
    		traitement de kw1 ...
                    if seq7(**kw1) is None:
                        return None
                    return True
     
                def c3(**kw):
     
    		...
     
                def c4(**kw):
    		...
     
                clauses = c0, c1, c2, c3, c4
                return next((x for x in (clause(**kw) for clause in clauses) if x), None)
    Désolé mais c'est un peu compliqué à suivre. En fait, on voit que les appels récursifs sont permanents mais c'est le principe même de l'algorithme
    (planification de séances de travail avec des contraintes d'enchainement). Les résultats (transfert de l'algorithme à PROLOG ou traitement en Python pur) en terme de performance sont sensiblement équivalents.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par tyrtamos Voir le message
    Bizarre, bizarre... Pourtant, je fais ça sur un PC récent avec une grosse mémoire (16Go), Windows 8.1 64bits et Python 3.4. Mais c'est Python "32bits" seulement: peut-on améliorer avec Python 64bits?.

    Quelqu'un peut-il expliquer ces curieux résultats?
    En fait, Python crash et la runtime Windows râle avec un "Exception Code: c00000fd", ce qui se traduit par "stack overflow".
    La stack dont on parle est celle du programme C appelé Python.exe.
    Si on veut l'augmenter, vous donnera différentes techniques.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    En fait, Python crash et la runtime Windows râle avec un "Exception Code: c00000fd", ce qui se traduit par "stack overflow".
    La stack dont on parle est celle du programme C appelé Python.exe.
    Mes recherches m'ont conduit vers le module -resource- https://docs.python.org/2/library/resource.html Mais apparemment c'est un service spécifique à UNIX ... et je suis sous Windows 8.1

  9. #9
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je crois avoir trouvé une belle astuce pour augmenter la pile nécessaire à la récursion.

    Si on y arrive difficilement et avec de trop petites limites pour le programme principal, on y arrive plus facilement dans un thread!!!

    Voilà une évolution de mon précédent programme qui le montre. L'astuce repose sur la double utilisation de threading.stack_size et sys.setrecursionlimit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import sys
    import threading
     
    #############################################################################
    def toto(c=0):
        c += 1
        print(c)
        toto(c)
     
    #############################################################################
    def monthread():
        try:
            toto()
        except Exception:
            pass
     
    #############################################################################
    if __name__ == "__main__":
        threading.stack_size(67108864)  # pile de 64MB (64*1024*1024)
        sys.setrecursionlimit(50000)
        print(sys.getrecursionlimit())
     
        thread = threading.Thread(target=monthread)
        thread.daemon = True
        thread.start()
        thread.join()
    La fonction monthread est ici nécessaire seulement pour qu'on ait un"try..except" côté thread à cause de toto qui tourne jusqu'à une exception.

    Avec ce code, la récursion de toto() va jusqu'à 49992 sans problème, que ce soit avec la version .py ou la version .exe après traitement par cx_freeze...

    Par contre, je ne sais pas jusqu'où ça marche!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  10. #10
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    Merci tyrtamos. Ton bout de code m'a permis de régler mon problème qui, en fait, n'était pas vraiment là où je croyais ...

    Après avoir adapté ton code à mon appli, le 1° test a été un échec. Ceci m'a surpris car je pensais vraiment que cette piste était la bonne.
    Ce qui était surprenant c'est que le programme ne rentrait même pas dans la 1° boucle d'itération (ce que j'aurais dû voir avant ...)
    J'avais positionné un - print - pour suivre, en mode console, l'évolution de l'itération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            # traitement des premières séquences
            for j in lJour1:
                print u"Traitement séquences intermédiaires 3 - {0}".format(j)
    	    ...
    J'ai donc supprimé le print comme c'était la 1° instruction (non essentielle) de la boucle. Et là, miracle (!), tout c'est bien déroulé jusqu'au prochain -print- qui était un peu plus loin ...
    J'ai donc supprimé tous les -print- et ton code s'est déroulé comme prévu.

    J'ai voulu en avoir le coeur net :
    Je suis repassé à la version antérieure (sans les threads) et le code fonctionne bien (??). Le problème viendrait donc des prints.
    J'ai testé plusieurs configurations :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
            # traitement des premières séquences
            for j in lJour1:
                #print u"Traitement séquences intermédiaires 3 - {0}".format(j)
                #print u"Traitement séquences intermédiaires 3 - %d" % j
                #print u"Traitement séquences intermédiaires 3 - j"
                print "Traitement sequences intermediaires 3 - {0}".format(j)
                #print "Traitement sequences intermediaires 3 - %d" % j
                #print "Traitement sequences intermediaires 3 - j"
                self.mainW.statusBar().showMessage(u"Traitement séquences intermédiaires 3 - {0}".format(j))
                kw = {'jour': -1, 'jourD': j, 'lJour': j}
                seq5(**kw)
                '''
                def monthread():
                    try:
                        seq5(**kw)
                    except Exception:
                        pass
                
                thread = threading.Thread(target=monthread)
                thread.daemon = True
                thread.start()
                thread.join()
                '''
            self.mainW.statusBar().showMessage(u"Traitement séquences intermédiaires 4")
    Toutes perturbent le fonctionnement de l'exécutable mais tout à fait de la même façon.
    Tous les prints avec la chaine en unicode bloquent à la première itération alors que les prints avec le string bloquent au milieu de l'itération (?!...)
    Dernier test : J'ai redirigé les sorties vers un fichier

    Avec les versions avec print "string", le programme se déroule normalement ... avec les unicodes, le fait de rediriger les sorties n'a rien changé.

    Ce comportement m'a quelque peu interpellé et j'aimerais bien avoir votre avis ...
    En tout état de cause, je conserve la version avec les "threads".

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Juste une idée d'explication.

    Les threads sont autonomes dans l'exécution, sauf lorsqu’ils doivent se partager des données, ou ... des entrées/sorties. Il faut alors organiser l'accès non-simultané aux ressources partagées.

    Donc: si tu veux vraiment mettre des prints, essaie de les synchroniser avec un verrou (threading.Lock).


    Je profite du message pour signaler: la solution avec thread pour bénéficier d'une grosse pile de récursion a tout de même une limite: elle ne devrait pas être utilisée avec des instructions graphiques, parce que les bibliothèques graphiques sont rarement "thread-safe".
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par tyrtamos Voir le message
    Juste une idée d'explication.

    Les threads sont autonomes dans l'exécution, sauf lorsqu’ils doivent se partager des données, ou ... des entrées/sorties. Il faut alors organiser l'accès non-simultané aux ressources partagées.
    Ben, si deux threads impriment en même temps çà fait au pire un mélange des sorties plutôt qu'afficher proprement chaque ligne.

    Exemple de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import threading
     
    def encode():
        print u'thread start'
        for x in range(10):
            s = u"Traitement sequences intermediaires 3 - {0}".format(x).encode('utf-8')
            print s 
     
    t = threading.Thread(target=encode)
    t.start()
    t.join()
    Normalement, lancé comme "script", pas de soucis.
    Maintenant, essayez de lancer la console et de faire un import du dit script.
    Ca devrait se vautrer à tous les coups en deadlock.
    Mais c'est çà ne fait que ce que raconte la documentation du module tout en bas "importing in threaded code":

    While the import machinery is thread-safe, there are two key restrictions on threaded imports due to inherent limitations in the way that thread-safety is provided:

    Firstly, other than in the main module, an import should not have the side effect of spawning a new thread and then waiting for that thread in any way. Failing to abide by this restriction can lead to a deadlock if the spawned thread directly or indirectly attempts to import a module.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    J'entends bien mais le plantage avec les prints apparait alors que je n'utilise pas les threads !
    Je suis repassé à la version antérieure (sans les threads) et le code fonctionne bien (??). Le problème viendrait donc des prints.

Discussions similaires

  1. crash excel pour cause -probable- de dépasement mémoire
    Par hector2 dans le forum Général VBA
    Réponses: 1
    Dernier message: 17/04/2009, 16h09
  2. Appels récursifs et stack overflow
    Par Argol_Medusa dans le forum C++Builder
    Réponses: 11
    Dernier message: 02/12/2008, 09h51
  3. Fibonacci : 2 appels Récursifs
    Par kamimar dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 22/06/2008, 04h09
  4. Appel récursif de DLLs
    Par ouinamp dans le forum Windows
    Réponses: 2
    Dernier message: 07/11/2007, 17h40
  5. [onresize] appels récursifs
    Par pmartin8 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 02/12/2005, 21h15

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