Les processus enfants engendrés par le multiprocessing partagent-ils des objets créés plus tôt dans le programme ?
Non pour Python < 3.8, oui pour Python ≥ 3.8 .
Les processus ont un espace mémoire indépendant.
Solution 1
Pour tirer le meilleur parti d'une grande structure avec beaucoup de travailleurs, faites ceci.
-
Écrivez chaque travailleur comme un "filtre" - lit les résultats intermédiaires à partir de stdin
fait le travail, écrit les résultats intermédiaires sur stdout
.
-
Connectez tous les travailleurs comme un pipeline :
process1 <source | process2 | process3 | ... | processn >result
Chaque processus lit, effectue des travaux et écrit.
Cette méthode est remarquablement efficace puisque tous les processus sont exécutés simultanément. Les écritures et les lectures passent directement par des tampons partagés entre les processus.
Solution 2
Dans certains cas, vous avez une structure plus complexe - souvent une sortie en éventail structure. Dans ce cas, vous avez un parent avec plusieurs enfants.
-
Le parent ouvre les données sources. Le parent bifurque vers un certain nombre d'enfants.
-
Le parent lit la source, ferme des parties de la source à chaque enfant fonctionnant simultanément.
-
Lorsque le parent atteint la fin, fermez le tuyau. L'enfant obtient la fin du fichier et termine normalement.
Les parties enfant sont agréables à écrire car chaque enfant lit simplement sys.stdin
.
Le parent doit faire preuve d'un peu de fantaisie pour faire naître tous les enfants et conserver les tuyaux correctement, mais ce n'est pas trop grave.
Fan-in est la structure opposée. Un certain nombre de processus fonctionnant indépendamment doivent entrelacer leurs entrées dans un processus commun. Le collecteur n'est pas aussi facile à écrire, car il doit lire à partir de nombreuses sources.
La lecture de plusieurs tuyaux nommés est souvent effectuée à l'aide de la fonction select
pour voir quels tuyaux ont une entrée en attente.
Solution 3
La consultation partagée est la définition d'une base de données.
Solution 3A - charger une base de données. Laissez les travailleurs traiter les données de la base.
Solution 3B - créer un serveur très simple en utilisant werkzeug (ou similaire) pour fournir des applications WSGI qui répondent à HTTP GET afin que les travailleurs puissent interroger le serveur.
Solution 4
Objet de système de fichiers partagé. Le système d'exploitation Unix propose des objets à mémoire partagée. Il s'agit simplement de fichiers qui sont mappés à la mémoire de façon à ce que les E/S de swapping soient effectuées au lieu des lectures tamponnées plus conventionnelles.
À partir d'un contexte Python, vous pouvez le faire de plusieurs façons
-
Écrivez un programme de démarrage qui (1) divise votre objet gigantesque d'origine en objets plus petits, et (2) lance des travailleurs, chacun avec un objet plus petit. Les objets plus petits pourraient être des objets Python pickled pour gagner un tout petit peu de temps de lecture de fichier.
-
Écrivez un programme de démarrage qui (1) lit votre objet gigantesque d'origine et écrit un fichier structuré en pages, codé en octets, utilisant seek
pour faire en sorte que les différentes sections soient faciles à trouver par une simple recherche. C'est ce que fait un moteur de base de données : il divise les données en pages, rend chaque page facile à trouver grâce à un moteur de recherche. seek
.
Créer des travailleurs ayant accès à ce grand fichier structuré en pages. Chaque travailleur peut rechercher les parties pertinentes et y effectuer son travail.
0 votes
Votre code tel qu'il est écrit appellera
marshal.load
pour le parent et pour chaque enfant (chaque processus importe le module).0 votes
Tu as raison, corrigé.
0 votes
Pour le "local en mémoire" et si vous voulez éviter la copie, ce qui suit pourrait être utile docs.python.org/library/
1 votes
Partager le nombre de processus engendrés (c'est-à-dire fork ou exec par exemple) est un double exact du processus appelant ... mais dans une mémoire différente. Pour qu'un processus puisse parler à un autre, il faut communication interprocessus ou une lecture/écriture IPC vers une partagé emplacement de la mémoire.
0 votes
Vous pouvez utiliser une fonction partielle à partir de functools, vous devrez faire
big_lookup_object
un argument dansdo_some_processing
il est également utile lorsque vous souhaitez passer un lambda à un programme de typePool.map()
ou en python purmap