Seite 1 von 1
Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Montag 24. Februar 2020, 09:26
von Chris87
Hallo,
ich habe einen Webscraper gebaut, der mit Multiprocess in mehreren Prozessen ausgeführt wird. Nun möchte ich aber, wenn eine bestimmte Bedingung eintritt, die erhobenen Werte in eine gemeinsame globale Liste schreiben und wenn eine weitere Bedingung eintritt, diese Liste an eine API senden.
Allerdings habe ich nun festgestellt, dass man aus den verschiedenen Prozessen nicht ohne weiteres auf eine globale Liste zugreifen kann.
Ich habe dann gesehen, dass man mit dem Process Manager eine "Shared List" erstellen kann und habe es exakt wie in diesem Beispiel ausprobiert:
https://stackoverflow.com/questions/406 ... 5#40682175
Allerdings bekomme ich dann die Meldung:
("name 'shared_list' is not defined",)
Dann habe ich gedacht, vielleicht ist es eine Alternative, von den verschiedenen Prozessen in die gleiche Tempdatei zu schreiben. Aber wenn ich es richtig verstanden habe, können mit "tempfile" erstellte Dateien auch nicht zwischen Prozessen geteilt werden.
Andere Alternative wäre halt, jeden Datensatz direkt (anstatt gebündelt) einzeln an die API zu senden.
Gibt es eventuell eine einfache Lösung für mein Problem? Ich könnte natürlich auch in eine lokale Datei im gleichen Verzeichnis wie meine Anwendung schreiben. Aber ist es überhaupt ratsam, mit verschiedenen Prozessen in eine Datei auf die Festplatte zu schreiben?
Vielen Dank.
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Montag 24. Februar 2020, 09:36
von sparrow
Was sind denn "die erhobenen Werte"? Das Ergebnis des Prozesses? Wenn ja, dann lass es per return zurück geben und führ die Liste im Hauptthread.
Und wenn "die erhobenen Werte" eine Art Zwischenergebnis sind, dann nutze eine
Queue.
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Montag 24. Februar 2020, 09:45
von __blackjack__
@Chris87: Vergiss das es ``global`` gibt. Das macht mehr Probleme als es löst. Eine gemeinsame Datei ginge wenn man die entsprechend sperrt wenn ein Prozess schreibt um Datensalat zu vermeiden. Eine Liste geht über einen `Manager`. Halt so wie in der Python-Dokumentation beschrieben und nicht wie in dem SO-Link. Am besten vermeidet man aber geteilten Zustand, wie auch die Dokumentation rät und benutzt Rückgabewerte und/oder Queue oder Pipe zur Kommunikation zwischen den Prozessen.
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Mittwoch 26. Februar 2020, 15:34
von Chris87
Also ich habe auch schon festgestellt, dass ich globale Variablen nicht in meiner Scrape()-Funktion, die per Multiprocessing aufgerufen wird verwenden kann. Ich muss dann alle Variablen an die Scrape()-Funktion als Parameter übergeben, wenn ich das richtig verstehe.
Hätte man bei Multithreading die gleichen Probleme? Und ist Multiprocessing / Threading überhaupt notwendig? Es geht mir ja nur darum, mehrere URLs gleichzeitig abzurufen und dann ein paar Werte auszulesen und auf ein paar Bedingungen zu überprüfen.
Ich habe nun gesehen, dass es auch Module wie "eventlet" oder "gevent", wäre das eine gute Alternative um diesen "Problemen" beim Multiprocessing aus dem Weg zu gehen? Ist halt die Frage, ob ich damit eine annähernd ähnliche Performance erreichen kann.
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Mittwoch 26. Februar 2020, 16:01
von sparrow
Wir haben dir doch die Lösung geschrieben...
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Mittwoch 26. Februar 2020, 16:19
von __blackjack__
@Chris87: Auch bei `eventlet` oder `gevent` kannst Du fast alle Probleme bekommen die es bei nebenläufiger Programmierung halt so gibt. Und selbst ohne jegliche Nebenläufigkeit verwendet man keine globalen Variablen. Bei nebenläufiger Programmierung halt erst recht nicht, weil die Probleme die das sowieso schon macht, noch mal potenziert werden.
Funktionen/Methoden sollten alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen. Grundsätzlich. Was ist denn daran so ein Problem?
Die Frage ob Du `multiprocessing` tatsächlich brauchst hängt davon ab welche Python Implementierung Du verwendest und wie stark das parallelisiert werden soll. Bei CPython, also der Referenzimplementierung von python.org braucht man `multiprocessing` für tatsächlich parallele Ausführung von beliebigem Code, denn Python-Bytecode kann bei CPython in einem Prozess immer nur in einem Thread ausgeführt werden. Threading bringt in dem Szenario etwas bei Code in C-Bibliotheken die das „Global Interpreter Lock“ (GIL) freigeben und damit tatsächlich parallel zu anderem C-Code laufen kann der das auch tut, und einem Thread der Python-Bytecode ausführt. Threads können also bei so Sachen wie XML parsen oder Numpy/Pandas-Operationen teilweise parallel laufen. Und blockierende Operationen wie warten auf Daten/Socketverbindungen können gleichzeitig passieren.
Bei `eventlet`, `gevent` & Co arbeitet nur ein Thread, man kann aber trotzdem mehrere Sockets ”gleichzeitig” bedienen weil immer wenn da etwas blockiert, andere Sockets bedient werden können. CPU intensive Aufgaben wie parsen/scrapen von HTML blockieren da und werden üblicherweise dann doch wieder in Threads oder Prozesse verlagert. Wenn man diese Art von asynchroner Programmierung haben möchte, würde man wahrscheinlich in modernem Python auch ``async``/``await`` und eine entsprechende Bibliothek wie `asyncio`, `curio` oder `trio` verwenden und dann `asks` statt `requests`.
Re: Auf "Gemeinsame Liste" oder "Tempdatei" aus verschiedenen Prozessen zugreifen
Verfasst: Mittwoch 26. Februar 2020, 16:40
von Chris87
Vielen Dank für deine Antwort und dass du dir die Zeit nimmst, das immer so gut zu erläutern. Hilft mir auf jeden Fall sehr
