[python, multitraitement] Comportement des exceptions lors de l'utilisation du multitraitement

Bien que le «multitraitement» soit utilisé pour le traitement parallèle en Python, le comportement lorsqu'un processus enfant est créé par le «multitraitement» présente quelques différences par rapport au comportement d'un appel de fonction normal.

Préparation

Cette fois, la fonction sleep_bug () est utilisée par souci de simplicité. C'est une fonction qui exécute «1/0» lorsque «i == 5» pour générer une erreur afin de générer intentionnellement une erreur lors de l'exécution.

import time

def sleep_bug():
    for i in range(10):
        print('sleeping %d' % i)
        if i == 5:
            1/0
        time.sleep(1)
    return i

sleep_bug()

 output
'''
sleeping 0
sleeping 1
sleeping 2
sleeping 3
sleeping 4
sleeping 5
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-44-d9f02a4cf7f3> in <module>
----> 1 sleep_bug()

<ipython-input-41-26bb27998e63> in sleep_bug()
     12         print('sleeping %d' % i)
     13         if i==5:
---> 14             1/0
     15         time.sleep(1)
     16 

ZeroDivisionError: division by zero
'''

Même si le processus enfant provoque une erreur, le processus parent continue de s'exécuter.

Dans un appel de fonction normal, si une erreur se produit dans la fonction appelée, le programme s'arrêtera là. Cependant, si un processus enfant créé à l'aide de Pool est amené à exécuter sleep_bug (), le processus enfant s'arrêtera avec une erreur, mais le processus parent ira jusqu'à la fin sans provoquer d'erreur.

from multiprocessing import Pool
p = Pool(1)
r = p.apply_async(sleep_bug)
p.close()
 p.join () # Attendez la fin du processus enfant.
print('Done')

 output
'''
sleeping 0
sleeping 1
sleeping 2
sleeping 3
sleeping 4
sleeping 5
Done
'''

Utilisez r.get () pour vous assurer que lorsqu'une erreur survient dans un processus enfant et qu'elle s'arrête, l'erreur est également transmise au processus parent. r.get () est une fonction qui attend normalement que le processus enfant se termine et affiche la valeur de retour du processus enfant, mais si une erreur se produit dans le processus enfant, r.get () Lèvera une exception et le processus parent s'arrêtera également là.

from multiprocessing import Pool
p = Pool(1)
r = p.apply_async(sleep_bug)
p.close()
output = r.get()
print('Done %d' % output)

# production
'''
sleeping 0
sleeping 1
sleeping 2
sleeping 3
sleeping 4
sleeping 5
---------------------------------------------------------------------------
RemoteTraceback                           Traceback (most recent call last)
RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 121, in worker
    result = (True, func(*args, **kwds))
  File "<ipython-input-41-26bb27998e63>", line 14, in sleep_bug
    1/0
ZeroDivisionError: division by zero
"""

The above exception was the direct cause of the following exception:

ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-50-fb8f5892e1a7> in <module>
      3     r = p.apply_async(sleep_bug)
      4     p.close()
----> 5     output = r.get()
      6     print('Done %d' % output)

/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py in get(self, timeout)
    655             return self._value
    656         else:
--> 657             raise self._value
    658 
    659     def _set(self, i, obj):

ZeroDivisionError: division by zero
'''

Si vous utilisez Process, une erreur sera affichée, mais le processus parent continuera jusqu'à la fin.

from multiprocessing import Process
p = Process(target=sleep_bug)
p.start()
p.join()
print('Done')

# production
'''
sleeping 0
sleeping 1
sleeping 2
sleeping 3
sleeping 4
sleeping 5
Process Process-35:
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-41-26bb27998e63>", line 14, in sleep_bug
    1/0
ZeroDivisionError: division by zero
Done
'''

Le processus enfant continue de s'exécuter même si le processus parent s'arrête

Le script ci-dessous attend 2 secondes pour que le processus enfant s'exécute, et le processus parent s'y termine avec sys.exit (). Comme indiqué dans l'exemple d'exécution ci-dessous, même si le processus parent s'arrête au milieu, le processus enfant continue de s'exécuter.

from multiprocessing import Pool
p = Pool(1)
r = p.apply_async(sleep)
p.close()
 r.wait (2) # wait 2 seconds for child process
sys.exit()

# production
'''
sleeping 0
sleeping 1
An exception has occurred, use %tb to see the full traceback.

SystemExit
sleeping 2
sleeping 3
sleeping 4
sleeping 5
sleeping 6
sleeping 7
sleeping 8
sleeping 9
'''

Recommended Posts

[python, multitraitement] Comportement des exceptions lors de l'utilisation du multitraitement
Vérifiez le comportement lors de l'attribution de Python
Comportement lors de la liste dans Python heapq
[TouchDesigner] Conseils pour la déclaration par python
[Python] Soyez prudent lorsque vous utilisez print
[Python] Raison du remplacement à l'aide de super ()
[Python] Quatre-vingt-dix-neuf tables utilisant des instructions for
Précautions lors de l'utilisation de phantomjs de python
Lors de l'utilisation de MeCab avec python dans virtualenv
Précautions lors de l'utilisation de six avec Python 2.5
Lors de l'utilisation d'expressions régulières en Python
Choses à surveiller lors de l'utilisation d'arguments par défaut en Python
Point 17 de la note Python efficace Respect de la certitude lors de l'utilisation d'itérateurs pour les arguments
Environnement de développement Python pour macOS utilisant venv 2016
Traitement d'exécution périodique lors de l'utilisation de tkinter [Python3]
[50 comptes] Transmission de clé à l'aide de Python pour Windows
Placement de Fabicon (lors de l'utilisation de Python, Flask, Heroku)
Précautions lors de l'utilisation de l'instruction for dans les pandas
Conseils pour utiliser python + caffe avec TSUBAME
Remarques sur l'utilisation de python (pydev) avec eclipse
Remarques sur la configuration d'un conteneur Docker pour l'utilisation de JUMAN ++, KNP, python
Une note utile lors de l'utilisation de Python après une longue période
python [pour moi]
vprof - J'ai essayé d'utiliser le profileur pour Python
Comment prendre plusieurs arguments lors d'un traitement parallèle à l'aide du multitraitement en python
Pandas Python: recherchez DataFrame à l'aide d'expressions régulières
[python, CPython] Comportement du GC lors de la levée d'une exception
Commencez à utiliser Python
Obtenir des informations sur les notes à l'aide du SDK Evernote pour Python 3
Précautions lors de l'utilisation de tf.keras.layers.TimeDistributed pour la couche personnalisée tf.keras
Encodage de caractères lors de l'utilisation du module csv de python 2.7.3
Recherche affinée des valeurs de race Pokemon à l'aide de Python
Points à garder à l'esprit lors de l'utilisation de Python pour ceux qui utilisent MATLAB
[Pour les débutants] Comportement inattendu si "\" est inclus lors de la définition du chemin en Python
Faisons un module pour Python en utilisant SWIG
Comportement lors de l'enregistrement d'un objet datetime python dans MongoDB
Scraping à l'aide de Python
[Python] Remarques sur l'accélération des algorithmes génétiques à l'aide du multitraitement
Qu'utilisez-vous lorsque vous testez avec Python?
Analysons les données Covid-19 (Corona) en utilisant Python [Pour les débutants]
Paramètres initiaux pour l'utilisation de Python3.8 et pip sur CentOS8
Recherche de balises pixiv et enregistrement d'illustrations à l'aide de Python
Squelettes extensibles pour Vim utilisant Python, Click et Jinja2
Structure de répertoire pour le développement piloté par les tests à l'aide de pytest en python
Précautions lors de l'utilisation de sqlite3 de macOS Sierra (10.12) avec le multitraitement
Paramètres initiaux lors de l'utilisation de l'API foursquare avec python
[Hikari-Python] Chapitre 07-01 Gestion des exceptions (erreurs et exceptions)
[Heroku] Mémo pour le déploiement d'applications Python à l'aide d'Heroku sous Windows [Python]
Erreur due à un conflit entre pythons lors de l'utilisation de gurobi
Vérifiez types_map lors de l'utilisation de mimetypes avec AWS Lambda (Python)
Méthode d'installation lors de l'utilisation de RealSense à partir de Python (édition pyenv)
Causes lorsque la version de Python ne peut pas être modifiée à l'aide de pyenv
Comment quitter lors de l'utilisation de Python dans Terminal (Mac)
Emplacement de modification du code lors de l'utilisation de plotly gratuitement
Erreur lors de l'exécution de commandes Python sans utiliser l'invite Anaconda
Articles à voir lorsque l'installation de Python + OpenCV échoue
Notes minimales lors de l'utilisation de Python sur Mac (édition pyenv)
Mémo de construction d'environnement d'apprentissage automatique par Python