Bonjours, le script suivant fonctionne presque normalement lorsqu'il est dans un objet mais alors à partir du moment que je l'ai mis dans une définition, les choses se sont compliquées!
Au début, les deux premiers passages se passaient à merveille mais dès la création du troisième objet, le calcul s’arrêtait en plein milieu, il se mettait en pause et les processeurs n'avait plus rien à se mettre sous la dent! (Je ne comprend pas pourquoi d’ailleurs!). Pour tenter d'y remédier, j'ai tout mis dans une définitions de façon à vraiment repartir à 0 à chaque fois que je la rappelle. Seulement, au lieu de faire une pause au troisième passage, Python exprime directement son mécontentement à travers le message suivant:

File "fractale_objet.py", line 2707, in calculage_rapide
matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
File "fractale_objet.py", line 2707, in <listcomp>
matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
File "/usr/lib/python3.4/multiprocessing/pool.py", line 599, in get
raise self._value
File "/usr/lib/python3.4/multiprocessing/pool.py", line 383, in _handle_tasks
put(task)
File "/usr/lib/python3.4/multiprocessing/connection.py", line 206, in send
self._send_bytes(ForkingPickler.dumps(obj))
File "/usr/lib/python3.4/multiprocessing/reduction.py", line 50, in dumps
cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <function fractale.<locals>.calculage_rapide.<locals>.calcul at 0x7ff331942a60>: attribute lookup calcul on __main__ failed

Bon, voila, je ne comprend pas vraiment le message mais il se trouve que là, il semble vraiment furax!

Voici le code qui le met dans cet état:
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
 
def calculage_rapide(identifiant, lecture):
	"""
        Rempli peu a peu la variable 'matrice'
        iters_max = nbr maximum d'itérations
        mod_carre = module maximum du nbr complex
        largeur = largeur de la matrice
        hauteur = hauteur de la marice
        z0 = premier terme de la suite
        suite = formule de récurence de la suite
        couleur = information que l'on enregistre dans la matrice
        xmin, xmax, ymin et ymax = dimension du plan complex
        iteration = True quand les itérations comptent et pas seulement le module
        nbr_couleur = Nombre totale de couleur différentes que peut avoir la fractale
        """
	def calcul(ligne, hauteur):
		"""
                Remplissage d'une partie de la matrice
                Retourne la ligne dans une liste
                """
		print("	Ligne n°"+str(ligne+1)+"----"+str(int(100*ligne/hauteur))+"%")
		liste = []								#On initialise la liste que l'on va remplir
		I = complex(0,1)							#Ainsi, I est considéré comme une variable
		y = (ymax-ymin)*ligne/(hauteur-1)+ymin					#La partie imaginaire du plan complex
		for colone in range(0,largeur):						#Pour chaque case de chaque ligne
			x = (xmax-xmin)*colone/(largeur-1)+xmin				#La partie réel du plan complex
			z = eval(z0)							#Création du premier rang de la suite
			c = 0								#Initialisation du compteur
			while (c<iters_max) and (((z.real**2)+(z.imag**2))<mod_carre):	#Tant qu'il n'y a aucune raison d'arrêter le calcul de la suite
				c+=1							#Incrémentation du compteur
				z = eval(suite)						#Calcul du rang suivant
			if iteration:							#Si la divergence de la suite compte
				c = c/iters_max						#On prend en compte le nombre d'itérations
			else:								#Si le module de la suite compte
				c = abs(z)/math.sqrt(mod_carre)				#Sinon, c'est le module de z qui est pris en compte
			liste.append(int(c*nbr_couleurs)/nbr_couleurs)			#Ce pxl est ajouté à la ligne
		return liste								#La ligne est la valeur de retour
 
	global matrice,fin								#On fait en sorte que la matrice soit accessible dans tous le programme
 
	if __name__ == "__main__":							#Si le programme en cours d’exécution est le programme principal
		tuple1, tuple2 = lecture.lire_tout(identifiant)				#On récupère les données qui permettent de créer l'image
		iters_max = tuple1[5]
		mod_carre = tuple1[6]
		largeur = tuple2[6]
		hauteur = tuple2[7]
		z0 = str(tuple1[7])
		suite = str(tuple1[8])
		xmin = tuple1[9]
		xmax = tuple1[10]
		ymin = tuple1[11]
		ymax = tuple1[12]
		iteration = tuple1[13]
		nbr_couleurs = tuple1[4]
 
		import multiprocessing							#On importe le module
		pool = multiprocessing.Pool()						#Il est possible de mettre en argument: processes=nbr_de_coeurs
 
		liste_res = []								#Tous les résultats seront enregistrés ici
		compteur = 0								#On met le compteur à 0
		for ligne in range(0,hauteur):						#Pour chacune des lignes à traiter
			if fin: return None						#Si il faut en finir, on s'arrète de suite
			compteur += 1							#On incrémente le compteur
			liste_res.append(pool.apply_async(calcul, args=(ligne, hauteur)))#On s'en charge
			compteur = compteur%(hauteur//10)				#C'est le nombre de boucles pandant lesquelles la matrice n'est pas actualisée
			if compteur == 0:						#Si on en est à la 16ème boucle
				pool.close()						#On arrète momentanément de charger la liste d'attente
				pool.join()						#On lance les calculs en liste d'attente
				matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
				pool = multiprocessing.Pool()				#On réinitialise le pooleur
				liste_res = []						#On vide la liste des lignes qui ont déjà étés calculées
		pool.close()								#Validation des dernières lignes
		pool.join()								#Lancement des derniers calculs
		matrice.extend([resultat.get() for resultat in liste_res])		#Récupération des derniers résultats
		fin = True
		print("		Fin du calcul")
		return None
En plus, ce qui complique le programme, c'est qu'il est impératif que la 'matrice' ait une portée global car un thread qui tourne en parallèle, se charge d'enregistrer chaque ligne sur le disque et de supprimer chaque ligne calculée affin de faire de la place en mémoire et de ne pas perdre de temps a la fin du calcul pour enregistrer l'image sur le disque.

Encore une fois, je suis preneur de toutes les pistes qui permettraient de corriger ce plantage, ou bien d'une autre idée de conception qui aurait le même effet final.