# Software puffert auf einmal Output - linuxbedingt?



## ivka_sto (26. Oktober 2009)

Hallo allerseits,

Ich habe soweit zahlreiche Foren durchforstet und ganz viele Posts gelesen, doch nichts gefunden, was mich auch einen Schritt weiterbringt - hoffentlich weiß einer von euch was 

Also, ich hab was programmiert, das eine externe Software startet und ihr die nötigen Parameter und Input gibt - mein Skript kontrolliert den Ablauf einer Simulation, die Simulationssoftware rechnet, und gibt die Werte als Output zurück. Jetzt hab ich das Problem, daß - auf Linux ausgeführt - sich das ganze ziemlich schleppt, weil auf Linux untypischerweise der Output gepuffert wird und erst geschrieben wird, wenn die Simulationssoftware fertig ist mit Rechnen. Ich würde das sehr gern anders haben, doch ich habe mir sagen lassen, daß dies eine Sache zwischen Linux und der externen Anwendung sei, und sich kaum beeinflußen ließe - stimmt das? Gibt es vielleicht einen Umweg, auf den ich den Output simultan schreiben lassen kann?

Viele Grüße,
ivka_sto


----------



## Enumerator (26. Oktober 2009)

Hi!

Da kann man was machen. Doch zuerst solltest Du uns wissen lassen, in welcher Sprache Du "was geschrieben hast"... 

Gruß
Enum


----------



## ivka_sto (26. Oktober 2009)

Das ging ja blitzschnell .. Danke 

Mein Skript ist in Python.


----------



## deepthroat (26. Oktober 2009)

Hi.

Wie startest du denn die externe Anwendung? Nutzt du das subprocess Modul?

Gruß


----------



## ivka_sto (26. Oktober 2009)

Ja, die externe Software wird über subprocess.popen gestartet:

```
simu = subprocess.popen(cmd, stderr = subprocess.PIPE)
simu.wait()
out_file = open('soundso', 'r')
out_content = out_file.readlines()
out_file.close()
for i in range (-1, -5, -1):
   k = out_content[i].strip()
   if (k.find('ExitNum') != -1):
      print 'exit number: ' + str(k[34:]).strip()
   else:
      pass
```


----------



## deepthroat (26. Oktober 2009)

ivka_sto hat gesagt.:


> Ja, die externe Software wird über subprocess.popen gestartet:
> 
> simu = subprocess.popen(cmd, stderr = subprocess.PIPE)
> simu.wait()
> ...


_
Ist das jetzt ein Scherz? Du rufst doch sogar explizit wait() auf und wartest erstmal bis die Anwendung beendet ist? Evtl. solltest du nochmal die Doku lesen...

Gruß

PS: Bitte verwende die entsprechenden Code-Tags ([code=python] ... [/code] für Python Code etc.)_


----------



## ivka_sto (26. Oktober 2009)

Nein, es ist kein Scherz. Mit wait() halte ich nur den Python-Skript an - das dürfte, meiner Meinung nach, das Schreiben der Output-Files in keinster Weise betreffen, da sie von der externen Anwendung generiert werden.

Das, was nach wait() steht (also das Lesen der Files) kommt an einer anderen Stelle, und der Code dazwischen hat mit meiner Frage nichts zu tun, deshalb hab ich den weggelassen.

Sorry für die Tags.


----------



## deepthroat (26. Oktober 2009)

ivka_sto hat gesagt.:


> Nein, es ist kein Scherz. Mit wait() halte ich nur den Python-Skript an - das dürfte, meiner Meinung nach, das Schreiben der Output-Files in keinster Weise betreffen, da sie von der externen Anwendung generiert werden.


Also dauert es dir einfach zu lange bis die externe Anwendung fertig ist? Wie kommst du darauf das es mit einem Ausgabepuffer zu tun hat? Evtl. solltest du mal den Autor des ext. Programmes fragen warum es so lange braucht?!

Hast du mal die Systemauslastung und die I/O kontrolliert?

Gruß


----------



## Raubkopierer (26. Oktober 2009)

> Mit wait() halte ich nur den Python-Skript an - das dürfte, meiner Meinung nach, das Schreiben der Output-Files in keinster Weise betreffen, da sie von der externen Anwendung generiert werden.



Aber das Auslesen des Files wird beeinflusst.
Das outfile wird doch erst geöffnet wenn die Simulation durchgelaufen ist. Also ist es kein Wunder, dass dein Skript die Daten erst dann bekommt, da es sie gar nicht früher abruft. Die Frage ist nun ob das externe Programm die Ausgabe erst schreibt wenn es fertig ist (was wahrscheinlich ist) oder ständig schreibt was einfach nur imperformant wäre.

Ich denke du solltest die communicate methode des popen objects nutzen:


```
simu = subprocess.popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
outcontent=""
while 1:
    print simu.communicate()[0] # communicate() returns a tuple (stdout,stderr)
    if whatever happens:
        break
```


----------



## ivka_sto (26. Oktober 2009)

Nein, auch nicht. Es stört mich, das der Output erst geschrieben wird, wenn die Simulationssoftware fertig gerechnet hat. Gerade weil einer der Entwickler gesagt hat, daß das untypisch sei, und es selber womöglich auf Linux geschoben hat - er hat gesagt, normalerweise wird der Output parallel mit dem Rechnen geschrieben. Dann könnte ich schon im Laufe der Rechnung einen Fehler erkennen, sonst rechnet das Programm weiter.

Hoffe die Beschriebung war jetzt genauer


----------



## ivka_sto (26. Oktober 2009)

ivka_sto hat gesagt.:


> Das, was nach wait() steht (also das Lesen der Files) kommt an einer anderen Stelle, und der Code dazwischen hat mit meiner Frage nichts zu tun, deshalb hab ich den weggelassen.



Es interessiert mich wirklich nur, ob es sich über Linux darauf wirken ließe, daß die Simulationssoftware erst nach Beenden der Simulation das Output schreibt.
communicate kommt aus anderen Gründen nicht in Frage.

Viele Grüße,
ivka_sto


----------



## Enumerator (26. Oktober 2009)

Hi!

Hast Du die Simulationssoftware mal "von Hand" gefüttert und Dich vergewissert, dass Sie erst gegen Ende des Prozesses Daten schreibt? 

Gruß
Enum


----------



## deepthroat (26. Oktober 2009)

ivka_sto hat gesagt.:


> Nein, auch nicht. Es stört mich, das der Output erst geschrieben wird, wenn die Simulationssoftware fertig gerechnet hat. Gerade weil einer der Entwickler gesagt hat, daß das untypisch sei, und es selber womöglich auf Linux geschoben hat - er hat gesagt, normalerweise wird der Output parallel mit dem Rechnen geschrieben. Dann könnte ich schon im Laufe der Rechnung einen Fehler erkennen, sonst rechnet das Programm weiter.


Nein könntest du nicht. Das Programm rechnet ja in jedem Fall weiter da du auf die Beendigung des Programmes wartest. Also irgendwas stimmt da mit deinem Ansatz überhaupt nicht.

Und wie soll ein Programm nach der Beendigung noch irgendwas schreiben?

Wie überprüfst du denn das es erst später  schreibt? Welches Dateisystem wird da eingesetzt?

Gruß


----------



## ivka_sto (26. Oktober 2009)

@deepthroat:
Doch, könnte ich schon. Wenn ich zur Laufzeit des Programms überprüfen kann, ob eine Fehlermeldung ausgegeben worde ist, werd ich auf das wait() natürlich verzichten. Nach Beendigung des Rechnens, nicht nach Beendigung des Programms.
Sorry, wie soll ich rausfinden, welches File-System eingesetzt wird?

@Enumerator: 
Ja, tut es trotzdem. Ich hab es auch manuell über die Konsole gestartet, kommt aufs Gleiche raus. Und zwar, es ist ein pid-File vorhanden, solange das Programm rechnet - solange wird nichts geschrieben. Dann verschwindet diese PID aus der Liste der aktuellen Prozesse, und gleich werden die Files unter einer anderen PID geschrieben. Ich denke, das Programm rechnet, bricht kurz ab, und schreibt dann den Output, der solange gepuffert worden ist. Anders kann ich es mir nicht erklären.


----------



## Raubkopierer (26. Oktober 2009)

Das ganze hängt in meinen Augen wirklich mit den IO-Scheduler des Kernels zusammen, der die Vorgänge entsprechend optimiert. Deshalb haben FDs ja auch die Methode flush() mit der man das Schreiben erzwingen kann.
An deiner Stelle würde ich einmal meine Codevariante testen, die von diesem Problem verschont bleiben sollte (zusätzlich gibt es in der Python Referenz noch einen Hinweis, dass wait() u.U. blockierend wirken kann wodurch dein Problem erklärt werden könnte. Stattdessen wird zu communicate() geraten).

Weiter wäre es wirklich gut zu wissen um welche Software es sich konkret handelt, damit man womöglich selbst einmal testen kann.

Edit: Zur Frage des Dateisystems: Selbiges ist für den Zeitpunkt des Schreibens vollkommen unerheblich. Ich weiß schon, dass ihr auf Systeme wie ReiserFS und XFS hinaus wollt, die in bestimmten Zyklen schreiben doch das sollte durch die Planung des Kernels keinen Einfluss auf das Auslesen besagter Daten haben. Wiederrum wird dies durch die Nutzung von communicate() und dem Verzicht auf jegliche File-Objects komplett eleminiert.



ivka_sto hat gesagt.:


> Gerade weil einer der Entwickler gesagt hat, daß das untypisch sei, und es selber womöglich auf Linux geschoben hat - er hat gesagt, normalerweise wird der Output parallel mit dem Rechnen geschrieben. Dann könnte ich schon im Laufe der Rechnung einen Fehler erkennen, sonst rechnet das Programm weiter.



Die Erklärung scheint recht mangelhaft zu sein von Seiten des Programmierers zumindestens was die fachliche Richtigkeit anbelangt. Ich bezweifel, dass er Threads benutzt (Threads sind pfui etc.  )um eine wirkliche Paralellisierung zu erreichen. Außerdem kommt hinzu, dass er fahrlässig die Verantwortung von sich weiß obwohl er womöglich einfach oben genanntes "flush" seiner Sprache vergessen hat. Natürlich sind das nur Vermutungen.


----------



## deepthroat (26. Oktober 2009)

Also, das hat so keinen Sinn. Bisher ist das alles nur ein einziger Wust von Informationshäppchen die uns hier rumraten lassen.

Erzähle uns erstmal genau was da passiert, welche Ausgabe erzeugt wird und was du dann wann machen willst.

Wie arbeitet das Programm? Welches Programm rechnet, welches simuliert, was wird wo aufgerufen? Welche Ausgabe willst du verarbeiten, wie sieht es zur Laufzeit aus?

Gruß


----------

