Ändern der Puffergröße in Multiprocessing.Queue

8

Also ich habe ein System mit einem Produzenten und einem Verbraucher durch eine Warteschlange von unbegrenzter Größe verbunden, aber wenn der Verbraucher wiederholt ruft, bis die leere Ausnahme ausgelöst wird, wird die Warteschlange nicht gelöscht.

Ich glaube, dass dies daran liegt, dass der Thread in der Warteschlange auf der Verbraucherseite, der die Objekte in den Socket serialisiert, blockiert wird, sobald der Socketpuffer voll ist, und so wartet, bis der Puffer Platz hat, jedoch ist es möglich für den Verbraucher zu rufen bekommen "zu schnell" und so denkt, dass die Warteschlange leer ist, wenn in der Tat der Thread auf der anderen Seite viel mehr Daten zu senden hat, aber einfach nicht serialisieren kann es schnell genug, um den Sockel für den Verbraucher leer zu erscheinen.

Ich glaube, dass dieses Problem gemildert werden würde, wenn ich die Puffergröße auf dem zugrunde liegenden Socket ändern könnte (ich bin Windows-basiert). Soweit ich sehen kann, was ich tun muss, ist etwas wie:

%Vor%

Wenn ich das obige tue, heißt das, dass wenn multiprompssing eine Warteschlange initialisiert, sie die neue Puffergröße verwendet, die ich in der Version von multiprocessing.connections gesetzt habe, die ich bereits importiert habe? Ist das richtig?

Auch ich glaube, dass dies nur Windows betrifft, da BUFSIZE nicht auf Linux-Maschinen verwendet wird, weil ihre alle Sockets standardmäßig auf 60 Kilobyte gesetzt sind?

Hat das schon mal jemand versucht? Würden diese Seiteneffekte auf Windows haben? Und was sind die grundlegenden Grenzen für Socket-Puffergrößen auf Windows?

=================== Ein Codebeispiel zum Vorführen ====================

%Vor%

Wenn dieses Beispiel unter Windows ausgeführt wird, werden in der Regel nur etwa 160.000 Elemente aus der Warteschlange abgerufen, da der Hauptthread den Puffer schneller leeren kann als vom Lieferanten nachgefüllt wird und schließlich versucht, die Warteschlange aus dem Puffer zu entfernen ist leer und meldet, dass es leer ist.

Sie können dieses Problem theoretisch durch eine größere Puffergröße beheben. Die zwei Zeilen an der Spitze, glaube ich, auf Windows-System, erhöhen die Standardpuffergröße für die Pipe.

Wenn Sie sie kommentieren, wird dieses Skript mehr Daten ziehen, bevor es beendet wird, da es viel höher ist. Meine Hauptfragen sind dann: 1) Funktioniert das tatsächlich? 2) Gibt es eine Möglichkeit, dass dieser Code die gleiche Größe des zugrunde liegenden Puffers in Windows und Linux verwendet 3) Gibt es unerwartete Nebenwirkungen beim Einstellen großer Puffergrößen für Pipes.

Mir ist bewusst, dass es im Allgemeinen keine Möglichkeit gibt zu wissen, ob Sie alle Daten aus der Warteschlange gezogen haben (- da der Lieferant permanent läuft und Daten sehr ungleichmäßig produziert), aber ich suche nach Verbesserungsmöglichkeiten auf bestmöglicher Basis.

    
phil_20686 29.11.2016, 17:16
quelle

1 Antwort

6

Aktualisierung:

nützlicher Link von Windows Pipe für Leute, die es in der Zukunft brauchen (der Link wird von OP zur Verfügung gestellt, phil_20686 ): Ссылка

Original:

BUFSIZE funktioniert nur, wenn die Plattform win32 ist.

multiprocessing.Queue wird am Anfang von Pipe erstellt. Wenn Sie BUFSIZE ändern, verwendet die von Ihnen generierte Warteschlange den aktualisierten Wert. siehe unten:

%Vor%

Wenn die Plattform win32 ist, ruft Pipe code folgenden Code auf:

%Vor%

Sie können sehen, dass, wenn duplex False ist, die Puffergröße 0 ist und die Puffergröße BUFSIZE ist.

inbuffer ist die Anzahl der Bytes, die für den Eingabepuffer reserviert werden müssen. 2 ** 16 = 65536, es ist die maximale Byteanzahl kann in einer Operation ohne Blockierung geschrieben werden, aber die Kapazität einer Puffergröße variiert zwischen Systemen, sie variiert sogar, wenn sie auf demselben System ist, daher ist es schwer, die Seite zu sagen Effekt, wenn Sie die Pipe die maximale Menge einstellen.

    
haifzhan 02.12.2016, 10:05
quelle