• Liebe User, bitte beachtet folgendes Thema: Was im Forum passiert, bleibt im Forum! Danke!
  • Hallo Gemeinde! Das Problem leidet zurzeit unter technischen Problemen. Wir sind da dran, aber das Zeitkontingent ist begrenzt. In der Zwischenzeit dürfte den meisten aufgefallen sein, dass das Erstellen von Posts funktioniert, auch wenn das Forum erstmal eine Fehlermeldung wirft. Um unseren Löschaufwand zu minimieren, bitten wir euch darum, nicht mehrmals auf 'Post Reply' zu klicken, da das zur Mehrfachposts führt. Grußworte.

fork - Ausgabe in die Konsole und Datei

cart

Technik/Software Forum
Mitglied seit
01.08.2002
Beiträge
4.873
Reaktionen
0
Ort
New York
Ich habe folgenden C Code:

Code:
/*
 * OS Praktikum 1
 * a4.c created on 26.03.2007
 * by moritz
 */

#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/procfs.h>
#include "error.h"

int main(int argc, char* argv[]) {
	FILE *file;
	char *datei="ausgabe";
	file = fopen(datei,"w");
	int child, i, sleep_parent, sleep_child, tofile=0;
	
	if(argc <3) {
		printf("sleeptime for parent: ");
		scanf("%d", &sleep_parent);
		printf("sleeptime for child: ");
		scanf("%d", &sleep_child);
	}
	else {
		sleep_parent = atoi(argv[1]);
		sleep_child = atoi(argv[2]);
	}
	if(sleep_parent < 0 || sleep_child < 0) 
		error_exit("negative time... nice try!",4706);
	child = fork(); // create a child and return its PID
		/* ab hier läuft der Code quasi 2mal! 
		 * einmal als Child und einmal als Parent
		 */
	if(child < 0)
		error_exit("error while creating a child",4707);
	/* wenn ich child bin, dann bin ich fuer mich 0 
	 * -> diese Schleife startet 
	 */
	if(child == 0) {
		for(i=0;i<=7;i++) {
			sleep((uint)sleep_child);
			if(tofile == 0)
				printf("c\n");
			else 
				fprintf(file,"c\n");
		}
		exit(0);
	}
	/* bin ich parent, ist child nicht 0, sondern die PID (Rückgabe von fork();!) 
	 * -> diese Schleife läuft
	 */
	else {
		for(i=0;i<=5;i++) {
			if(tofile == 0)
				printf("p\n");
			else 
				fprintf(file,"p\n");
			sleep((uint)sleep_parent);
		}
		/* parent wartet auf child, ansonsten kommt auf der Konsole eine Ausgabe
		 * obwohl man schon weitere Befehle eingeben kann!
		 */
		waitpid(child,NULL,0);
	}
	return 0;	
}
Eine Ausgabe auf die Konsole sieht so aus:
p
p
c
p
p
c
p
c
p
c
c
c
c
c

Eine in die Datei so:
c
c
c
c
c
c
c
c
p
p
p
p
p
p

Da kommt mir doch glatt die Frage, warum das in der Datei sortiert ist und auf der Konsole nicht. Kann mir das mal jemand erklären?
 

RRA^StArFiRe

Guest
was macht das programm denn genau?
wie ich das sehe, erzeugst du da n child-thread in der mainmethode und lässt sie dann die schleifen durchlaufen.
was passiert, wenn du nach deinem printf n fprint machst?
also in die konsole und in die datei.

setz ma testweise n kurzes timeout nach dem fprintf


btw. du machst das mit nem linux/unix compiler oder?
also unter windows testen is da nix *gg*


könnt aber auch sein, dass der buffer des writers nur an einem thread hängt, und die eingaben vom parent hinten angestellt werden, bis der child die exklusivrecht abgibt. aber kA, hab nicht unbedingt so die ahnung vom c filewriter.
auf jeden fall haste doch quasi 2 threads, wo jeder thread n printer mitmn pointer auf die datei hat, oder?
also entweder flushed der die ausgaben erst am ende in die datei, wobei dann der printer von thread1 erst die eingaben reinschreibt und danach thread2...
oder der indexpointer erhöht sich im anderen thread nicht, wenn ein eintrag geschrieben wurde.. aber dann sähs nicht sortiert aus glaub ich ma x_X


hab mir grad die fprintf klassenbeschreibung durchgelesen.
der schreibt des in nen stream rein und flusht das wohl am ende.
versuch ma n fflush(file); nachm schreiben

notfalls musste dir ne static klasse als filewriterstream definieren, damit die beiden threads auf dieselbe klasse bzw output zugreifen. zum vergleich, von der konsole hast du auch nur eine instanz, egal wieviele threads du startest.
von dem bei dir erzeugtem filewriter haste mit dem fork() für jeden thread eine instanz erzeugt bzw kopiert und ist danach nicht mehr ein und derselbe.
 

[MSMC]Jesus C

Guest
OS-Praktikum FH-Muenster?

Bei welchen Werten für die sleeps tritt dieses Verhalten auf?
 
Mitglied seit
03.08.2002
Beiträge
707
Reaktionen
0
ausgabe in datei: fully buffered stream
ausgabe auf standard output: line buffered stream (output nach newline)

würdest du also bei ausgabe auf standard output das '\n' bei printf() weglassen,
dann wäre die ausgabe auch geordnet (sofern der buffer davor nicht "geflusht" wird).

buffering kannst du ändern mit setvbuf (ansi c standard), also z.b.
setvbuf(file, NULL, _IOLBF, 0); /* jetzt verhält sich file wie stdout */
setvbuf(stdout, NULL, _IOFBF, 0); /* jetzt verhält sich stdout wie file */

übrigens: fork() erzeugt keinen neuen thread, sondern einen neuen prozess.
 

cart

Technik/Software Forum
Mitglied seit
01.08.2002
Beiträge
4.873
Reaktionen
0
Ort
New York
@Jesus: Ja ;) Übrigens ist es unabhängig von irgendwelchen Werten!

Es liegt wohl daran, dass bei einer Ausgabe mit fprintf der ganze Spaß halt erst in den Buffer geschrieben wird und die eigentlich Ausgabe, egal ob in Datei oder auf die Shell, erst erfolgt, wenn der Buffer voll ist oder der Prozess beendet wird. Habe das Programm auch noch umgeschrieben bevor ich es abgegeben habe, so dass das jetzt beides äquivalent funktioniert. Thx trotzdem für die Tipps ;)
 
Oben