Einstellung kleinerer Pufferspeicher für sys.stdin?
Ich bin mit memcached mit dem folgenden bash-Befehl Muster:
memcached -vv 2>&1 | tee memkeywatch2010098.log 2>&1 | ~/bin/memtracer.py | tee memkeywatchCounts20100908.log
zu versuchen, die Spur unerreicht bekommt, setzt für Schlüssel-Plattform breit.
Den memtracer Skript ist unten und so funktioniert wie gewünscht, mit ein kleines Problem. Gerade die intermediate Größe der Protokolldatei, memtracer.py nicht anfangen, Eingang bis memkeywatchYMD.melden
etwa 15-18K in der Größe. Gibt es einen besseren Weg zum Lesen von stdin oder vielleicht ein Weg, um schneiden Sie die Puffer-Größe auf unter 1k für schnellere Reaktionszeiten?
#!/usr/bin/python
import sys
from collections import defaultdict
if __name__ == "__main__":
keys = defaultdict(int)
GET = 1
SET = 2
CLIENT = 1
SERVER = 2
#if <
for line in sys.stdin:
key = None
components = line.strip().split(" ")
#newConn = components[0][1:3]
direction = CLIENT if components[0].startswith("<") else SERVER
#if lastConn != newConn:
# lastConn = newConn
if direction == CLIENT:
command = SET if components[1] == "set" else GET
key = components[2]
if command == SET:
keys[key] -= 1
elif direction == SERVER:
command = components[1]
if command == "sending":
key = components[3]
keys[key] += 1
if key != None:
print "%s:%s" % ( key, keys[key], )
InformationsquelleAutor David | 2010-09-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie vollständig zu entfernen Pufferung von stdin/stdout durch die Verwendung von python
-u
Flagge:und die man-Seite verdeutlicht:
Darüber hinaus die änderung der Pufferung für eine vorhandene Datei wird nicht unterstützt, aber Sie kann machen ein neues file-Objekt mit dem gleichen zugrunde liegenden Datei-Deskriptor als eine vorhandene und möglicherweise unterschiedlichen Puffern, mit os.fdopen. I. e.,
sollte binden
newin
auf den Namen eines file-Objekts, das liest derselben FD als standard-Eingabe, sondern puffert nur etwa 100 bytes zu einer Zeit (und Sie können weiterhin mitsys.stdin = newin
Verwendung der neuen file-Objekt als standard-Eingabe von dort ab). Ich sage "sollte", weil dieser Bereich verwendet, um eine Reihe von bugs und Probleme auf einigen Plattformen (es ist ziemlich hart-Funktionalität zu bieten cross-Plattform-mit voller Allgemeinheit) - ich bin mir nicht sicher, was Ihr Zustand jetzt ist, aber ich würde auf jeden Fall empfehlen, die Gründliche Tests auf allen Plattformen von Interesse, um sicherzustellen, dass alles glatt geht. (-u
entfernen Pufferung vollständig, mit dem Sie arbeiten weniger Probleme auf allen Plattformen, wenn, die möglicherweise Ihren Anforderungen entsprechen).Leider Python 3 noch hartnäckig öffnet
stdin
in Gepufferter text-Modus. Nurstdout
undstderr
betroffen sind die-u
jetzt wechseln.Irgendwelche Workarounds für Python ist3? Vielleicht eine event-driven library/option?
Ich habe versucht, mit gio_channels, und habe es funktioniert - aber das Verhalten ist genau das gleiche: keine Ausgabe bis
enter
gedrückt wirdDieser arbeitete für mich in Python 3.4.3:
os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
InformationsquelleAutor Alex Martelli
Können Sie einfach
sys.stdin.readline()
stattsys.stdin.__iter__()
:Dies gibt mir die line-buffered liest mit Python 2.7.4 und 3.3.1 Python auf Ubuntu 13.04.
Wie ich verstanden habe, war die Frage "gibt es einen besseren Weg zum Lesen von stdin," [um zu vermeiden, Eingabe-Puffer-Probleme bei der Verwendung eines Python-Skript in einer pipeline], und meine Antwort (drei Jahre zu spät wie es sein kann) ist "ja, verwenden Sie
readline
statt__iter__
". Aber vielleicht meine Antwort ist Plattform-abhängig, und Sie haben noch Puffer von Problemen, wenn Sie versuchen, den obigen code?Ahkey, ich verstehe. Ich meinte VIEL kleinere puffergrößen ( z.B. 80 Byte oder weniger ) für die Pufferung. Für 2.7 Sie können keinen Einfluss auf diejenigen, die Puffer-Größen, ohne das -U flag Alex erwähnt in seiner Antwort.
Interessant Alex nicht fangen, github.com/certik/python-2.7/blob/... Sie sind richtig, dass readline ist wahrscheinlich schneller als es nutzt getc inkrementell während file_internext Puffer 8192 gemäß der Definition in der Quelle.
Das ist ziemlich wichtig-ich sehe Programme nicht interaktiv genug durch die Pufferung von stdin (statt reagieren sofort). Ich wusste nicht, diese vor.
InformationsquelleAutor Søren Løvborg
Den
sys.stdin.__iter__
noch line-buffered, man kann einen iterator, der verhält sich meist identisch (Stoppt bei EOF, in der Erwägung, dassstdin.__iter__
nicht) mit die 2-argument-formiter
, um einen iterator, dersys.stdin.readline
:Oder bieten
None
the sentinel (beachten Sie aber, dass dann müssen Sie behandeln die EOF-Bedingung selbst).Was Sie hier vorschlagen ist hier die beste Lösung, die ich gesehen habe, um dieses schreckliche problem; ich bin zu gehen Sie durch alle meine python-code und ersetzen Sie "for line in sys.stdin". Ich sehe es eigentlich aufgelistet in der ref-Seite, die Sie bezeichnet. Was noch nicht klar ist mir... warum auf der Erde ist "für Zeile in sys.stdin" Verhalten sich anders als "for line in iter(sys.stdin.readline, "):"? Soweit ich sehen kann, Sie sind semantisch identisch, mit der Ausnahme, dass die erstere version ist das Verhalten, was aussieht, um mich wie einen bösen Fehler, Verhalten, niemand konnte jemals wollen. Wenn jemand ein Gegenbeispiel würde ich gerne sehen.
bei der Iteration über stdin ich bin damit einverstanden, dass das Verhalten ist seltsam und bug-wie, aber wenn die Datei nicht von stdin Lesen 8k gleichzeitig wird die Leistung verbessert.
Warum sollte es eine Rolle, ob der input-stream in Frage stdin oder nicht? (Vielleicht sind Sie Sinn zeigen sich einige Unterschiede zwischen den terminals, Dateien und pipes? Aber solche Unterschiede sind unabhängig davon, ob es ist stdin.) Und wenn Sie sagen, das Lesen 8k gleichzeitig wird die Leistung verbessert-- Verbesserung der Leistung im Vergleich zu was?? Ich glaube nicht, dass ich vorgeschlagen habe oder befürwortet jedes Verhalten, das überhaupt Lesen würden weniger als 8k auf einmal bei 8k ist auf die Eingabe.
BTW ich eingereicht bugs.python.org/issue26290 auf diesem vor einer Weile: "fileinput und 'for line in sys.stdin' seltsame Spott der Eingang Pufferung".
InformationsquelleAutor Antti Haapala
Dieser arbeitete für mich in Python 3.4.3:
Den Dokumentation für
fdopen()
sagt, es ist nur ein alias füropen()
.open()
hat eine optionalebuffering
parameter:In anderen Worten:
InformationsquelleAutor Denilson Sá Maia
Nur so konnte ich es mit python 2.7 war:
vom Python-nicht blockierende Konsolen-Eingabe . Diese komplett deaktivieren Sie die Pufferung und unterdrücken auch das echo.
EDIT: in Bezug auf Alex ' Antwort, die erste Aussage (Aufruf python mit
-u
) nicht möglich ist, in meinem Fall (siehe shebang Einschränkung).Die zweite proposition (duplizieren fd mit kleineren Puffer:
os.fdopen(sys.stdin.fileno(), 'r', 100)
) nicht funktioniert wenn ich mit einem Puffer von 0 oder 1, wie es für eine interaktive Eingabe, und ich muss jedes Zeichen gedrückt, um sofort verarbeitet werden.tty.setcbreak
ist nicht über python-Pufferung aber der kernel tty layer Pufferung Eingang. Damit dies gilt nicht für Rohre.InformationsquelleAutor calandoa