staging.inyokaproject.org

Textdatei hat scheinbar leeren Inhalt - Synchronisationsproblem

Status: Ungelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

herakles

Anmeldungsdatum:
6. November 2006

Beiträge: 74

Moin!

In einem bash-script rufe ich zwei selbst programmierte C-Programme auf. Das eine Programm schreibt in eine Textdatei ("erstes_programm"), das andere liest anschließend aus dieser Datei wieder Daten aus ("zweites_programm"). Ich weiß, dass es andere Möglichkeiten gibt, Kommunikation zwischen Prozessen zu ermöglichen, es geht mir hier aber um das Verständnis eines bestimmten beobachteten Verhaltens, und zwar wie folgt:

Wenn ich den Aufruf der beiden Programme direkt aufeinander folgen lasse, dann kann "zweites_programm" oft (aber nicht immer) den Inhalt der von "erstes_programm" erstellten Datei nicht lesen. Es erkennt 0 Zeilen. Füge ich einen kleinen sleep ein, funktionert es aber wie erwartet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
range=$(seq 1 18)
for i in $range;
do
      cd ${MAIN_DIR}
      cd erstes_programm
      ./erstes_programm-R ${i}
      cd ${MAIN_DIR}
      cd zweites_programm
      # fitness des tipps berechnen
sleep 0.03
      ./zweites_programm
      RES=$?
      ERGEBNIS=`expr $RES + $ERGEBNIS`
done

Füge ich das "sleep 0.03" ein, läuft es korrekt. Mit einem "sleep 0.01" funktioniert es beispielsweise nicht.

Meine Fragen:

a) Wieso ist das so?

b) Wie macht man es richtig (sicher nicht mit einem sleep(1) - ich habe schon versucht, ein sync(1) einzufügen, aber das ändert nichts)

Interessierte Grüße

Herakles

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

herakles schrieb:

Meine Fragen:

a) Wieso ist das so?

Zeig mal das erste C-Programm (oder zumindest den Teil, der die Datei zum Schreiben öffnet und wieder schließt). Und dann wäre noch interessant, auf was für einem Dateisystem das ganze stattfindet und ob es da noch Besonderheiten wie Synchronisationsdienste ala Dropbox oder ähnliches gibt.

herakles

(Themenstarter)

Anmeldungsdatum:
6. November 2006

Beiträge: 74

Im "ersten_programm" ist der Teil, der sich um die Datei dreht, folgendermaßen aufgebaut:

1
2
3
4
5
FILE *Pfilename_FILE;

Pfilename_FILE= fopen( "../results/test", "w" );
fprintf( Pfilename_FILE, "%hhd:%hhd=%hhd:%hhd\n", id1_U8, id2_U8, test1_U8, test2_U8 );
fclose( Pfilename_FILE);

Im "zweiten_programm" ist der entsprechende Code wie folgt:

1
2
3
4
5
6
7
8
FILE *Pfilename_FILE;

Pfilename_FILE= fopen( "../results/test", "r" );
while( !feof( Pfilename_FILE) )
{
	fscanf( Pfilename_FILE, "%hhd:%hhd=%hhd:%hhd\n", &id1_U8, &id2_U8, &test1_U8, &test2_U8);
}
fclose( Pfilename_FILE);

Wie im bash-script zu erkennen, werden beide Programme jeweils erst nach Ablauf des jeweils anderen Programms aufgerufen. Da ich jeweils ein fclose(3) durchführe, sollte alles passen, oder nicht?

Grüße Herakles

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

herakles schrieb:

Wie im bash-script zu erkennen, werden beide Programme jeweils erst nach Ablauf des jeweils anderen Programms aufgerufen.

Machen die sonst noch irgendwas erwähnenswertes, das dazu führt, dass die Bash den Zeitpunkt, an dem sich das Programm beendet, nicht richtig ermitteln kann (z.B. forken)?

Da ich jeweils ein fclose(3) durchführe, sollte alles passen, oder nicht?

Du wertest die Rückgabe-Werte der aufgerufenen Funktionen nicht aus - solange du nicht explizit prüfst, ob die alle erfolgreich waren, gibt es endloses Potential für unentdeckte Fehler - es könnte z.B. sein, dass die Variablen, die du mit fprintf() in die Datei schreiben willst nicht immer erfolgreich entsprechend des Format-String umgewandelt werden können.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@herakles: Das beschriebene Verhalten kann so eigentlich nicht sein. Wenn das erste Programm endet, dann gibt es die Daten in der Datei, egal ob man die sofort ausliest oder vorher ein bisschen wartet.

Die while-Schleife in zweiten Programm scheint nicht so viel Sinn zu machen, weil im ersten Programm ja nur eine Zeile geschrieben wird.

Bei einer Bash würde ich das aufaddieren so schreiben: ((ERGEBNIS += RES)) statt ERGEBNIS=….

Über den Rückgabecode gibt man keine Zahlen zurück. Also ich meine keine die nicht irgendwelche Statusinformation enthalten. Wenn irgendwer den Prozess beispielsweise terminiert, dann hat $RES den Wert 143, bei einem SIGKILL den Wert 137. Auch wenn das Programm mit einer Speicherzugriffsverletzung beendet wird, hat $RES einen Wert. Und den addiert das Skript dann jeweils auf $ERGEBNIS als sei nichts passiert. Das ist keine gute Idee.

herakles

(Themenstarter)

Anmeldungsdatum:
6. November 2006

Beiträge: 74

Danke für die Hinweise! Da ich das Problem nicht in den Griff bekommen habe, sind nun beide Teilprogramm in ein gemeinsames Programm gewandert und damit kann ich nun arbeiten.

Grüße Herakles

Antworten |