Python-multiprocessing: Wie kann ich ZUVERLÄSSIG umleiten von stdout von einem Kind-Prozess?

NB. Ich habe gesehen, Log-Ausgabe von multiprocessing.Prozess - leider, es gibt keine Antwort auf diese Frage.

Erstelle ich ein child-Prozess (unter windows) über multiprocessing. Ich will alle des child-Prozesses auf stdout-und stderr-Ausgabe umgeleitet zu werden in einer log-Datei, sondern erscheinen auf der Konsole. Der einzige Vorschlag, den ich gesehen habe, ist für das Kind Prozess sys.stdout in eine Datei. Dies gilt jedoch nicht effektiv umleiten stdout Ausgabe, aufgrund des Verhaltens des stdout-Umleitung auf Windows.

Um das problem zu veranschaulichen, erstellen Sie eine Windows-DLL mit dem folgenden code

#include <iostream>

extern "C"
{
    __declspec(dllexport) void writeToStdOut()
    {
        std::cout << "Writing to STDOUT from test DLL" << std::endl;
    }
}

Dann erstellen und ausführen eines python-Skript wie das folgende, welches die Einfuhren dieser DLL ein und ruft die Funktion:

from ctypes import *
import sys

print
print "Writing to STDOUT from python, before redirect"
print
sys.stdout = open("stdout_redirect_log.txt", "w")
print "Writing to STDOUT from python, after redirect"

testdll = CDLL("Release/stdout_test.dll")
testdll.writeToStdOut()

Um zu sehen, die das gleiche Verhalten wie mir, es ist wahrscheinlich notwendig für die DLL gebaut werden, gegen eine andere C-Laufzeit als das man Python verwendet. In meinem Fall, python erstellt mit Visual Studio 2010, aber meine DLL ist gebaut mit VS 2005.

Dem Verhalten, das ich sehe, ist, dass die Konsole zeigt:

> stdout_test.py

Writing to STDOUT from python, before redirect

Writing to STDOUT from test DLL

Während die Datei stdout_redirect_log.txt endet mit:

Writing to STDOUT from python, after redirect

In anderen Worten, die Einstellung sys.stdout ist fehlgeschlagen Umleitung des stdout-Ausgabe generiert, die von der DLL. Dies ist nicht verwunderlich angesichts der Art der zugrunde liegenden APIs für stdout-Umleitung in Windows. Ich habe auf dieses problem in der Muttersprache/C++ - Ebene vor und nie einen Weg gefunden, um zuverlässig umleiten von stdout in einem Prozess. Es wurde extern erstellt werden.

Dies ist eigentlich der Grund, ich bin der Einführung eine untergeordnete Prozess - es ist so, dass ich eine Verbindung herstellen können, das von außen auf den Rohren und gewährleisten damit, dass ich bin abfangen aller seiner Ausgabe. Ich kann auf jeden Fall dazu starten Sie den Prozess manuell mit pywin32, aber ich würde sehr gerne in der Lage sein, die Einrichtungen des multiprocessing, insbesondere die Möglichkeit der Kommunikation mit dem Kind-Prozess über eine multiprocessing-Pipe-Objekt, um den Projektfortschritt zu informieren. Die Frage ist, ob es irgendeinen Weg gibt, um beide verwenden multiprocessing für seine IPC-Einrichtungen und zuverlässig umleiten des Kindes stdout und stderr Ausgabe in eine Datei.

UPDATE: Sie sich den Quellcode für multiprocessing.Prozesse, es ist ein statisches Element, _Popen, die aussieht wie es verwendet werden kann, um das überschreiben der Klasse verwendet zum erstellen des Prozesses. Wenn es auf None gesetzt ist (default), verwendet es eine multiprocessing."forking"._Popen, aber es sieht so aus, indem er sagte

multiprocessing.Process._Popen = MyPopenClass

Könnte ich überschreiben der Prozess der Schöpfung. Jedoch, obwohl, ich könnte ableiten dies von multiprocessing."forking"._Popen, wie es aussieht, würde ich die Kopie einer Reihe von internen Sachen in meiner Implementierung, das klingt flockig und nicht sehr zukunftssicher. Wenn das die einzige Wahl, die ich denke, würde ich wohl zu plump das ganze manuell mit pywin32 statt.

  • Können Sie mit der Win32-API zum starten des teilprozesses, oder hat es zu tun mit bestehenden Python-Bibliotheken?
  • Ja, ich erwähnte in der Frage, dass "ich kann auf jeden Fall dazu starten Sie den Prozess manuell mit pywin32". Es schien nur eine Schande, aufzugeben, die auf höherer Ebene, unabhängig von der Plattform multiprocessing-Modul, weil von dem, was scheint wie eine triviale bisschen fehlende Funktionalität - die Fähigkeit zu geben stdin/stdout-handles für das Kind.
  • Der Ansatz, den ich nehme (es sei denn, jemand kommt mit einer besseren alternative) ist, starten Sie den Prozess über den subprocess-Modul, mit stdin/stdout in eine Datei umgeleitet, und verwenden Sie eine native Windows-named pipe für den Fortgang der Kommunikation.
  • Trifft es nicht richtig funktionieren, wenn Sie umleiten, sys.stdout des übergeordneten Prozesses, vor dem starten des Kindes?
InformationsquelleAutor Tom | 2011-10-10
Schreibe einen Kommentar