Bonjour à tous les pythoneux

J'espère que vous allez bien, je passe consulter votre sagesse car je suis dans une drôle d'impasse.
Je développe gentiment un module pour effectuer du calcul sur un réseau routier à partir des bilblothèques GDAL et Networkx, et pour accélérer une fonction un peu lourde, j'essaye de passer par du multiprocessing (via la bilbiothèque standard)

Le hic, c'est que dans une de mes fonctions, le process semble ne pas vouloir finir... C'est à dire qu'il a bien fini son travail (le print de fin de fonction apparaît bien) mais qu'on ne passe pas à la suite du code. Je pense que ça doit venir d'une mauvaise utilisation du multiprocessing, quelqu'un pour m'éclairer ?

Le code en question

Algo_Isochrone est le "worker" et c'est lui qui arrive à terme sans pour autant finir. je n'ai aucune erreur, le dernier message apparaissant dans la console est bien "les ajouts sont faits", mais après plus rien.
Draw_Isochrones_MP est la fonction qui va faire appelle à la précédente en créer le nombre adéquat de process.


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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 
 
def Algo_Isochrone(graph,departs,distance,ponderation,q) :
    for depart in departs :
        print('depart actuel : '+str(depart))
        extremites=[]
        chemins=[{"nodes":[depart],"length":0}]
        while len(chemins)>0 :
            print('      encore '+str(len(chemins))+' chemins a parcourir')
            new_chemins=[]
            for chemin in chemins :
                nodes = chemin["nodes"]
                end_node=nodes[-1]
                length = chemin["length"]
                #on choppe les voisins
                neighbours = graph.neighbors(end_node)
                #on verifie la distance restante pour chaque voisin
                for neighbour in neighbours :
                    #si le point ne fait pas deja partie du chemin
                    if neighbour not in nodes :
                        #il faut encore verifier que la distance n'est pas depassee
                        edge = graph[end_node][neighbour]
                        if ponderation=='GEOM_LENGTH' :
                            wkt = edge['wkt']
                            geom = ogr.CreateGeometryFromWkt(wkt)
                            length2 = geom.Length()
                        else :
                            length2 = edge[ponderation]
                        if (length+length2)< distance :
                            #on cree un nouveau chemin
                            new_chemin = copy.deepcopy(chemin)
                            new_chemin["nodes"].append(neighbour)
                            new_chemin["length"]=length+length2
                            new_chemins.append(new_chemin)
                        else :
                            #on est arrive au bout, on doit donc le stocker dans extemites
                            reste = distance - length
 
                            extremites.append({"depart":depart, "nodes":chemin["nodes"], "reste":reste ,"arrivee":chemin["nodes"][-1]})
                    elif len(neighbours)==1 and  neighbour in nodes :
                        extremites.append({"depart":depart, "nodes":chemin["nodes"], "reste":0 ,"arrivee":chemin["nodes"][-1]})
            #on remplace les anciens chemins par les nouveaux
            chemins=copy.deepcopy(new_chemins)
        print('tous les chemins ont ete trouves !!!')
        #on stocke les extremite trouvees pour ce noeud de depart dans le dictionaire isochrones
        q.put([depart,extremites])
        print('les ajouts sont faits')
        return True
 
 
 
def Draw_Isochrones_MP(network,essai,departs,distances,ponderation,extra,name,coeurs) :
    """
    On cherche ici a realiser des isochrones a partir d'un reseau existant
        depart est une liste de dictionnaire associant des champ (clef unique) a des valeurs et le nom de la couche de point
    """
    ID_name = departs[0].values()[0]
    #chargement du network
    infos = pickle.load(file(network+"/infos.obj","rb"))
    graph = pickle.load(file(infos.Essai[essai].Emplacement,'rb'))
    nodes=graph.nodes(data=True)
 
    #recuperation des noeuds de departs
    dep_ok=[]
    for points in departs :
        champ = points['champ']
        value = points['value']
        points_name = points['name']
        for element in nodes :
            if element[1].has_key(champ) and element[1]['PT_NAME']==points_name :
                if element[1][champ]==value  :
                    dep_ok.append(element[0])
    if len(dep_ok)==0 :
        print 'les noeuds demandes sont introuvables'
    else :
        results={}
        print('voila les points de departs :'+str(dep_ok))
        #on itere pour chaque distance
        for dist in distances :
            isochrones={}
            print('iteration sur la distance : '+str(dist))
            #on itere sur chacun des points de departs
            q=Queue()
            nb = len(dep_ok)
            repartition=nb/coeurs
            dep=0
            if nb>2 :
                for d in range(coeurs) :
                    dep=(d)*repartition
                    compte=repartition
                    if d==coeurs-1 and repartition*coeurs!=nb :
                        compte=nb-(d*repartition)
                    ss_dep = dep_ok[dep:compte]
                    p=Process(target=Algo_Isochrone,args=[graph,ss_dep,dist,ponderation,q])
                    p.start()
                    p.join()
            elif nb==2 :
                p = Process(target=Algo_Isochrone,args=[graph,[dep_ok[0]],dist,ponderation,q])
                p.start()
                p.join()
                p1 =p = Process(target=Algo_Isochrone,args=[graph,[dep_ok[1]],dist,ponderation,q])
                p1.start()
                p1.join()
            elif nb==1 :
                print('lancement du process')
                p = Process(target=Algo_Isochrone,args=[graph,[dep_ok[0]],dist,ponderation,q])
                p.start()
                p.join()
            #stockage des isochrones
            z=0
            print('process termine')
            while not q.empty():
                z+=1
                values = q.get()
                isochrones[values[0]]=values[1]
            print("nombre d'isochrones traites "+str(z))
            #on enregistre les isochrones trouves pour chacune des distances
            results[dist] = isochrones
    #a ce stade on a un un dictionnaire contenant pour chaque distance des sous dictionnaire : un pour chaque point de depart.
    #Les points d'arrive sont aussi des dictionnaires contenant le noeud d'arrivee, la distance manquante et tous ses predecesseurs
 
    #creation de la sortie
    spatiale_reference=osr.SpatialReference()
    spatiale_reference.SetWellKnownGeogCS(infos.Projection)
    driver = ogr.GetDriverByName('ESRI Shapefile')
    output_shp = driver.CreateDataSource(infos.Workspace+'/SHP/temp/ISOCHRONES/'+name+'.shp')
    output_layer = output_shp.CreateLayer('layer',spatiale_reference)
    champ1=ogr.FieldDefn('depart', ogr.OFTString)
    champ2=ogr.FieldDefn('distance', ogr.OFTReal)
    output_layer.CreateField(champ1)
    output_layer.CreateField(champ2)
    q=Queue()
    ATTRS = networkx.get_node_attributes(graph,ID_name)
    #creation des geometries
    for dist in results.keys() :
        deps = results[dist].keys()
        nb = len(deps)
        repartition=nb/coeurs
        dep=0
        if  nb >2 :
            for d in range(coeurs) :
                dep=(d)*repartition
                compte=repartition
                if d==coeurs-1 and repartition*coeurs!=nb :
                    compte=nb-(d*repartition)
                part_departs = deps[dep:compte]
                p=Process(target=Build_Geom_Isochrone,args=[graph,part_departs,ATTRS,results,dist,extra,q])
                p.start()
                p.join()
        elif nb==2 :
            p=Process(target=Build_Geom_Isochrone,args=[graph,[deps[0]],ATTRS,results,dist,extra,q])
            p.start()
            p.join()
            p1=Process(target=Build_Geom_Isochrone,args=[graph,[deps[1]],ATTRS,results,dist,extra,q])
            p1.start()
            p1.join()
        elif nb==1 :
            p=Process(target=Build_Geom_Isochrone,args=[graph,[deps[0]],ATTRS,results,dist,extra,q])
            p.start()
            p.join()
            #on cree les feature feature de sortie
            z=0
        while not q.empty():
            z+=1
            values = q.get()
            print(values)
            ID_dep = values['depart']
            polygon = values['geom']
            new_feature = ogr.Feature(output_layer.GetLayerDefn())
            new_feature.SetField('depart',ID_dep)
            new_feature.SetField('distance',dist)
            new_feature.SetGeometry(polygon)
            output_layer.CreateFeature(new_feature)
    print('nombre de feature creees : '+str(z))
    output_shp.Destroy()
    return results
Désolé, c'est un peu velu, mais ça reste très modeste j'imagine.

En tout cas un grand merci d'avance à ceux qui prendront un peu de temps pour y jeter un oeil ou pour m'aiguiller

A plus