Multiprocessing führt zum Absturz von Python und gibt einen Fehler aus, der möglicherweise in einem anderen Thread ausgeführt wurde, als fork () aufgerufen wurde

79

Ich bin relativ neu in Python und versuche, ein Multiprocessing-Modul für meine for-Schleife zu implementieren.

Ich habe eine Reihe von Bild-URLs in img_urls gespeichert, die ich herunterladen und mit Google Vision anwenden muss.

if __name__ == '__main__':

    img_urls = [ALL_MY_Image_URLS]
    runAll(img_urls)
    print("--- %s seconds ---" % (time.time() - start_time)) 

Dies ist meine runAll () -Methode

def runAll(img_urls):
    num_cores = multiprocessing.cpu_count()

    print("Image URLS  {}",len(img_urls))
    if len(img_urls) > 2:
        numberOfImages = 0
    else:
        numberOfImages = 1

    start_timeProcess = time.time()

    pool = multiprocessing.Pool()
    pool.map(annotate,img_urls)
    end_timeProcess = time.time()
    print('\n Time to complete ', end_timeProcess-start_timeProcess)

    print(full_matching_pages)


def annotate(img_path):
    file =  requests.get(img_path).content
    print("file is",file)
    """Returns web annotations given the path to an image."""
    print('Process Working under ',os.getpid())
    image = types.Image(content=file)
    web_detection = vision_client.web_detection(image=image).web_detection
    report(web_detection)

Ich erhalte dies als Warnung, wenn ich es ausführe und Python abstürzt

objc[67570]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67570]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67567]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67567]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67568]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67568]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67569]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67569]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67571]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67571]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67572]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67572]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
SriTeja Chilakamarri
quelle
Bist du auf OSX? Dann gibt Ihnen dieser Fehlerbericht vielleicht einige Hinweise.
IonicSolutions
Oh ja, ich bin unter OSX, danke, dass Sie mich auf den Link hingewiesen haben.
SriTeja Chilakamarri
Immer noch kein Glück versucht das OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YESwie erwähnt einzustellen, immer noch den gleichen Fehler bekommen. @ IonicSolutions
SriTeja Chilakamarri
Leider habe ich keine spezifischen Kenntnisse zu diesem Thema. Ich kann nur Google verwenden, um verwandte Probleme zu finden, z . B. diese mögliche Problemumgehung .
IonicSolutions
1
Dies ist darauf zurückzuführen, dass Apple das MacOS- fork()Verhalten seit High Sierra geändert hat . Die OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yesVariable deaktiviert das sofortige Absturzverhalten, das das neuere ObjectiveC-Framework normalerweise standardmäßig jetzt erzwingt. Dies kann sich auf jede Sprache auswirken, die unter fork()MacOS Multithreading / Multiprocessing ausführt >= 10.13, insbesondere wenn "native Erweiterungen" / C-Code-Erweiterungen verwendet werden.
TrinitronX

Antworten:

202

Dieser Fehler tritt aufgrund der zusätzlichen Sicherheit auf, um das Multithreading in Mac OS High Sierra einzuschränken. Ich weiß, dass diese Antwort etwas spät ist, aber ich habe das Problem mit der folgenden Methode gelöst:

Legen Sie eine Umgebungsvariable .bash_profile fest, um Multithreading-Anwendungen oder -Skripts gemäß den neuen Sicherheitsregeln für Mac OS High Sierra zuzulassen.

Öffnen Sie ein Terminal:

$ nano .bash_profile

Fügen Sie am Ende der Datei die folgende Zeile hinzu:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

Speichern, beenden, Terminal schließen und Terminal erneut öffnen. Überprüfen Sie, ob die Umgebungsvariable jetzt festgelegt ist:

$ env

Sie sehen eine Ausgabe ähnlich der folgenden:

TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/pn/vasdlj3ojO#OOas4dasdffJq/T/
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.E7qLFJDSo/Render
TERM_PROGRAM_VERSION=404
TERM_SESSION_ID=NONE
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

Sie sollten jetzt in der Lage sein, Ihr Python-Skript mit Multithreading auszuführen.

jonnyjandles
quelle
10
Das hat es tatsächlich für mich gelöst. Ich wollte einen großen Pandas-Datenrahmen über mehrere Threads hinweg iterieren und stieß auf dasselbe Problem, das von der Operation beschrieben wurde. Diese Antwort löste das Problem für mich. Der einzige Unterschied ist, dass ich diese env-Variable mit dem Skript gesetzt habe, das ich ausgeführt habe:OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES python my-script.py
rodrigo-silveira
3
Vielen Dank! Für Interessierte funktionierte dies für mich unter macOS Mojave.
Nmetts
Dies löste mein Problem, aber mein Skript verwendete Multi-Processing
Lollerskates
Es hat auf meinem Computer mit macOS Mojave funktioniert, aber dann laufen meine Pytest-Tests nicht mehr parallel. Vorher stürzte es ab, aber zumindest war es schnell ...
onekiloparsec
1
Diese Umgebungsvariable hat mein Problem gelöst, Ansible lokal auf meinem Mac (Catalina)
auszuführen