re
Nochmal was zu den Zombies: Wenn man das Child einfach nochmal forken lässt, und dann das Grandchild die Arbeit machen lässt, während sich das Child sofort wieder beendet, und man den Vater-Prozess auf das Child warten lässt via wait(), was kein Problem ist, da Child ja sofort zurückkehrt, dann entstehen erst gar keine Zombies
Nachteil ist, dass man 2x forkt, was natürlich ineffizient ist (aber dafür sehr portabel).
das is eigentlich egal du musst halt nach printf nen fflush machen damit der buffer auch auf stdout geschrieben wird
und falls printf <0 dann haste halt nen fehler oder die verbindung wurde vom client unterbrochen
ich habs auch mit printf gemacht so sieht der code schön sauber aus
was deine 2 forks angeht
If a child as requested by pid has already
exited by the time of the call (a so-called "zombie" process), the function returns immediately. Any system resources used by the child are
freed.
würdest du dann nicht einen prozess erstellen der darauf wartet dass sein child endet aber dann selbst zu nem zombie wird? so hab ich das jedenfalls verstanden
da stellt sich mir die frage ob man nen beendeten prozess nicht nochmals verwenden könnte @SOS team: geht das?
If the argument buf is NULL, only the mode is affected; a new buffer will be allocated on the next read or write operation. The
setvbuf function may only be used after opening a stream and before any other operations have been performed on it.
ka ob ich das hier richtig verstanden hab aber ich dachte immer das die stdio streams je nach system eine betriebssystem bedingte größe haben
aber wenn ich den auszug aus der manpage dort lese würde das ja heissen
dass die wieder und wieder neuen speicher allokieren und das kann ja wohl nicht ernsthaft ne implementierung sein die man sich wünscht schliesslich will man sich seinen speicher nicht auf diese weise fragmentieren
weiss vllt jemand mehr darüber ob die stdio streams feste größe haben oder nicht?
äh…nee
Dadurch, dass man 2 mal forkt, und sozusagen die erste Generation sich gleich wieder umbringt, passiert folgendes:
Der Vaterprozess muss nicht auf wait() warten, da der Kindprozess ja sofort stirbt.
Dadurch wird der Enkelprozess zum Waisen, und stellt sein SIGCHLD an init zu, was ihn dann sofort aufräumt, sobald er sich beendet.
Also keine Zombies mehr
@lord of code:
Buffer & OS: Ja, haben sie, aber die kanns du änderen. Sogar auf shell-ebene, wenn ich mich recht erinner. Ansonsten hab ich eine etwas andere docu:
timed.o: In function `main':
timed.o(.text+0xac): undefined reference to `__xnet_socket'
timed.o(.text+0xf0): undefined reference to `__xnet_bind'
timed.o(.text+0x128): undefined reference to `listen'
timed.o(.text+0x178): undefined reference to `accept'
collect2: ld returned 1 exit status
Die Zeile ist dein Fehler … du bindest current_time.o zu timed.o … das ist glaub ich nicht so ganz das was du willst …
Füge einfach ein timed hinter -o ein dann sollte es funktionieren … also
Aufgabestellung
In der Aufgabenstellung steht nichts von send und recv. Bei TCP-Sockets sind diese
Funktionen IMHO ueberfluessig bzw. ungeschickt. Ansonsten duerft Ihr natuerlich
auch send und recv in der Aufgabe verwenden, genauso wie fdopen oder dup. Wenn Ihr
etwas explizit nicht verwenden duerft bzw. sollt, dann wird dieses in den Tafel-Uebungen bzw.
auf dem Aufgabenblatt so auch gesagt.
Tip: Ich wuerde einfach fdopen verwenden und mit printf bzw. puts arbeiten.
Das Abfragen von errno ist wirklich schlechter Stil. Bei readdir hat
euer Uebungleiter/in das bestimmt auch so gesagt.(bzw. haette sollen) Es gilt nie errno Abfragen sondern immer den Rueckgabewert!!
Ausnahme: Es gibt keinen sinnvollen Rueckgabewert, oder keinen anderen sinnvollen Mechanimus. Bsp. readdir.
send und recv haben einen sinnvollen Rueckgabewert.
Haettest Du diesen verwendet, dann haettest Du auch keinen Frust gehabt. – QED
Um das Programm auf einer Sun zu kompilieren muss man noch zwei Liabaries mit angeben beim Kompilieren. Dazu muss man die Optionen ‘-lsocket -lnsl’ mit angeben.
Dann funktioniert timed auch unter SunOS.
Das einzige was ich nicht ferstehe ist, das in der ‘struct sockaddr_in’, die ich dem accept() uebergebe keine IP-Adresse, des Clients drinsteht.
@Wawi: Wie hier schon mehrmals erwähnt hat sich das Problem gelöst. Ich dachte das send irgendwie nicht blicken würde, wenn der Socket geschlossen wird. Immerhin wurde keine Fehlermeldung gegeben(da der Prozess zu deem zeitpunkt schon tot war). Und meine Lösung taugt dann doch ganz gut das Child kontrolliert zu beenden. Dass ich -1 von send zu dem Zeitpunkt (nicht mehr) abgefangen hab ist eine andere Sache.
Ach ja und mit fork hat das zu tun, da es im Childprozessärger macht.